的专栏
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:1847
解决:244
-
题目描述:
-
给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。
如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。
-
输入:
-
输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。
-
输出:
-
对于每组测试数据,输出为一个整数,表示a和b的公约数个数。
-
样例输入:
样例输出:
-
8 16 4
22 16 2
-
#include <iostream> using namespace std; int gcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); } int main(){ int a, b, c, i, ans; while(cin>>a>>b){ c = gcd(a, b); ans = 0; for(i = 1; i * i < c; i++) if(c % i == 0) ans += 2;//因为因子是关于根下c两边对称的,所以需要加2 if(c == i * i) ans += 1;//如果 c == i * i,此时需要把i这个因子加上 cout<<ans<<endl; } }
#include <cstdio> int pri[10000]; bool mar[10001]; //求1-10000的素数,保存到pri[]中.个数为pri[0] void fuc(){ for(int i = 2; i <= 10000; i++){ if(!mar[i]){ pri[ ++pri[0]] = i; for(int j = i * i; j <= 10000; j += i) mar[j] = true; } } }; //求a,b最大公约数 int gcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); }; int main(){ fuc(); int a, b, c, cnt, ans; while(~scanf("%d%d", &a, &b)){ ans = 1; c = gcd(a, b); for(int i = 1; i <= pri[0]; i++){ cnt = 0; if(c % pri[i])continue; //求c可以整除pri[i]最高次幂 while(!(c % pri[i])){ cnt++; c /= pri[i]; } ans *= (cnt + 1); //现在求得cnt = 2;pri[i] = 3; //在cnt个pri[i]有cnt + 1种因子组合,从pri[i]的0次方到cnt次方.比如1, 3, 3 * 3; //那现在的因子个= 之前的因子个数 * (现在的因子组合个数),因为都是互不相同因子,所以乘积也是相同的 if(c == 1)break; } if(c != 1) ans *= 2;//a与b的公因子在(sqrt(a)到a之间 或者在 sqrt(b)到b之间)最多有一个公因子 //如果c != 1说明此时有一个公因子.因为求的是1 - 10000的素数,所以此时公因子个数需要乘以2; printf("%d\n", ans); } }
-
出处:
http://blog.csdn.net/bebabyron/article/details/8686520
感谢:babyron