-
求正整数N(N>1)的质因数的个数。相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。
九度1207:质因数的个数 题目地址:http://ac.jobdu.com/problem.php?pid=1207
题目描述:
-
输入:
-
可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。
-
输出:
-
对于每组数据,输出N的质因数的个数。
-
样例输入:
-
120
-
样例输出:
-
5
-
提示:
-
注意:1不是N的质因数;若N为质数,N是N的质因数。
-
-
解题思路:
-
利用素数筛选法的反向思维,当i = 2的这轮循环完成时,n的因数已经不再包含2以及2的倍数,同理当i=3时,n的因数不再包含3和3的倍数。所以当i=4时,n%4==0不成立,自动跳过合数因数...
-
#include<iostream> #include<cmath> using namespace std; int main(){ int n,res,i; while(cin >> n){ res = 0; for(i = 2;i <= sqrt(n + 1);i++){ if(n % i == 0){ while(n % i == 0){ res++; n = n / i; } } } if(n > 1) res++; cout << res << endl; } return 0; } /************************************************************** Problem: 1207 User: cherish Language: C++ Result: Accepted Time:10 ms Memory:1532 kb ****************************************************************/
-
九度1104:整除问题 题目地址:http://ac.jobdu.com/problem.php?pid=1104
题目描述:
-
给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。
-
输入:
-
两个整数n(2<=n<=1000),a(2<=a<=1000)
-
输出:
-
一个整数.
-
样例输入:
-
6 10
-
样例输出:
-
1
-
- 解题思路:
- 由于n最大时可以是1000,此时求n的阶乘再循环除以a,会超时。所以可以用分解质因数的方法来解该题。令n!=b,分别对a和b分解质因数。
- 所以,对于a中的每一个质因数p,如果b的质因数中p的指数小于a中p的指数,则b不可能被a整除。所以我们需要依次测试a的每一个质因数,确 定该质因数在b中的幂指数是在a中的多少倍,所有的倍数中最小(非负正整数)的即是我们要求的k;
-
另外,这题有一个比较简单的解法。不用分解质因数的方法,也可以避免求阶乘使数据变大。把每一个当前数看做是(A*a+B)*a^k,前面的A 对于后面的计算没有意义,所以每次计算只需要保留比a小的B。#include<iostream> using namespace std; #define N 1001 int prime[N]; void initprime(){ int i,j,cnt; for(i = 0;i < N;i++) prime[i] = 1; prime[0] = prime[1] = 0; for(i = 2;i < N;i++){ for(j = 2;i * j < N;j++){ if(prime[i] == 1) prime[i * j] = 0; } } } //分别用来存储n!和a的每个质因子的幂 int prime1[N]; int prime2[N]; int main(){ initprime(); int n,a,i,ans; while(cin >> n >> a){ for(i = 0;i < N;i++) prime1[i] = prime2[i] = 0; for(i = 2;i <= n;i++){//计算n!的质因数及该质因数的个数 if(prime[i] == 1){ int t = n; while(t){ prime1[i] += t / i; t = t / i; } } } ans = 100000; for(i = 2;i <= a;i++){ if(prime[i] == 1){ while(a % i == 0){ prime2[i]++; a = a / i; } } if(prime2[i] != 0){ if(prime1[i] / prime2[i] < ans) ans = prime1[i] / prime2[i]; } } cout << ans << endl; } } /************************************************************** Problem: 1104 User: cherish Language: C++ Result: Accepted Time:10 ms Memory:1532 kb ****************************************************************/
-
#include<iostream> using namespace std; int main(){ int n,a,k,i,tmp; while(cin >> n >> a){ k = 0; tmp = 1; for(i = 2;i <= n;i++){ tmp *= i; while(tmp % a == 0){//在计算n!的过程中先把能整除a的数整除a,只保留不能整除的部分 k++; tmp /= a; } tmp %= a;//保留不能整除a的余数 } cout << k << endl; } return 0; } /************************************************************** Problem: 1104 User: cherish Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
-
-
九度1087:约数的个数 题目地址:http://ac.jobdu.com/problem.php?pid=1087
题目描述:
-
输入n个整数,依次输出每个数的约数的个数
-
输入:
-
输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。
-
输出:
-
可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。
-
样例输入:
-
5 1 3 4 6 12
-
样例输出:
-
1 2 3 4 6
-
- 解题思路: 用1 <= i <=num一个一个计算的方法在当num= 1000000000时超时。事实上只需要计算1<=i<=sqrt(num),因为当i>sqrt(num)时比较小的那个因数肯定已经计算过。
-
-
#include<iostream> #include<cmath> using namespace std; int caldiv(int x){ int i,res; res = 0; for(i = 1;i < sqrt(x);i++){ if(x % i == 0) res += 2; } i = sqrt(x); if(i * i == x) res++; return res; } int main(){ int n,i,tmp; while(cin >> n){ if(n == 0) break; for(i = 0;i < n;i++){ cin >> tmp; cout << caldiv(tmp) << endl; } } return 0; } /************************************************************** Problem: 1087 User: cherish Language: C++ Result: Accepted Time:150 ms Memory:1532 kb ****************************************************************/