题目1493:公约数
时间限制:1秒
内存限制:32 兆
特殊判题:否
提交:3863
解决:752
- 题目描述:
给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。
如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。
输入:
输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。
- 输出:
对于每组测试数据,输出为一个整数,表示a和b的公约数个数。
- 样例输入:
- 8 16
22 16 - 样例输出:
- 4
2 - 分别求出a,b素因数的个数npa1,npa2,...,npan和npb1,npb2,...npbn,再求出来整数因数的个数(min(npa1,npb1)+1)*...*(min(npan,npbn)+1),即为a和b的公约数个数。但有一个WRONG ANSWER!
#include<stdio.h> const int MAXN=10001; bool p[10005];//p[i]表示i是否为素数 int npa[10005],npb[10005]; int pa[100],pb[100]; int prime() { p[0]=false; p[1]=false; for (int i=2;i<=MAXN;i++) p[i]=true; for (int i=2;i<=MAXN;i++) { if (!p[i]) continue; for (int j=i*i;j<=MAXN;j+=i) p[j]=false; } return 0; } int min(int a,int b) { return (a<b?a:b); } int main() { prime(); long a,b; while(scanf("%ld%ld",&a,&b)!=EOF) { int ca=0,cb=0; int num=1; for(int i=2;i<=MAXN;i++) { npa[i]=0; npb[i]=0; } for(int i=2;i<=MAXN;i++) { bool sa=false,sb=false; while (p[i] && a%i==0) { npa[i]++; a=a/i; sa=true; } while (p[i] && b%i==0) { npb[i]++; b=b/i; sb=true; } if (sa && sb) num=num*(min(npa[i],npb[i])+1); } if (a==1 && b==1) { printf("%d\n",num); continue; } else if (a==b) { num=num*2; printf("%d\n",num); } } return 0; }
- 先求出a和b的最大公约数,然后通过求素因数的个数c1,c2...cn,再求出来整数因数的个数(c1+1)*(c2+1)*...*(cn+1),即为a和b的公约数个数。
#include<stdio.h> bool p[10000];//p[i]表示i是否为素数 int primer[3000]; int primerNum[3000]; int primerSize; int prime_init()//素数筛法 { p[0]=p[1]=false; for (int i=2;i<=10000;i++) p[i]=true; primerSize=0; for (int i=2;i<=10000;i++) { if (!p[i]) continue; primer[primerSize++]=i; for (int j=i*i;j<10000;j+=i) p[j]=false; } return 0; } int main() { prime_init(); long a,b; while (scanf("%ld%ld",&a,&b)!=EOF) { if (a<b) { long tmp=b; b=a; a=tmp; } while(b!=0) //辗转相除法求最大公约数 { long tmp=a % b; a=b; b=tmp; } int num=1; for (int i=0;i<primerSize;i++) { int c=0; while(a%primer[i]==0) { c++; a=a/primer[i]; } num=num*(c+1); } if (a!=1) num*=2; printf("%d\n",num); } return 0; }