首页 > 代码库 > UVa 10139 - Factovisors
UVa 10139 - Factovisors
题目:判断n!能否整除m。
分析:数论。先将m拆成素数的积的形式,再判断n!中对应每个素数的个数,是否大于m的即可。
首先,打表计算50000内素数,用这些素数除不尽的数一定也是素数,不过最多只有一个;
然后,分解m成素数的积的形式,统计每个素数因子的个数;
最后,判断n!中每个素数因子的个数是否大于m中对应的素数个数;
设f(n,p)为n!中素数p的个数,则有f(n,p)= f(n/p,p)+ n/p;
{ 能被p整除的数为:p,2p,3p,..,p^2,p(p+1),..,p^3,..,p^k ≤ n < p^(k+1);
共有,n/p个,全部除以p则剩余的含有p因数的数字有,p,2p,..,p^2,..,p^3,..,p^(k-1);
因此有f(n,p)= f(n/p,p)+ n/p ,n < p 时 f(n,p)= 0 }
说明:最近忙着最实验,有几天没有刷题了╮(╯▽╰)╭。
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; int prime[50000]; int used[50000]; int p[50],k[50]; int size(int n, int p) { if (n < p) return 0; return size(n/p, p) + n/p; } int main() { memset(used, 0, sizeof(used)); int count = 0; for (int i = 2 ; i < 50000 ; ++ i) if (!used[i]) { used[i] = 1; prime[count ++] = i; for (int j = 2*i ; j < 50000 ; j += i) used[j] = 1; } int n,m; while (~scanf("%d%d",&n,&m)) { int move = 0,save = 0,t = m; memset(k, 0, sizeof(k)); while (t > 1 && move < count) { while (t%prime[move] == 0) { t /= prime[move]; k[save] ++; } if (k[save]) p[save ++] = prime[move]; move ++; } if (t > 1) { p[save] = t; k[save] = 1; save ++; } int flag = 1; for (int i = 0 ; i < save ; ++ i) if (size(n, p[i]) < k[i]) { flag = 0; break; } if (flag && m) printf("%d divides %d!\n",m,n); else printf("%d does not divide %d!\n",m,n); } return 0; }
UVa 10139 - Factovisors
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。