题目1493:公约数

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);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值