http://ac.jobdu.com/problem.php?pid=1493
-
题目描述:
-
给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。
如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。
-
输入:
-
输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。
-
输出:
-
对于每组测试数据,输出为一个整数,表示a和b的公约数个数。
-
样例输入:
-
8 16 22 16
-
样例输出:
-
4 2
#include <stdio.h> int gcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); } int main(){ int a, b, c, i, ans; while(~scanf("%d%d", &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这个因子加上 printf("%d\n", ans); } }
#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);
}
}