题目:
输入二个正整数x0,y0(2<=x0<=100000,2<=y0<=100000),求出满足下列条件的P,Q的个数
条件: 1.P,Q是正整数
2.要求P,Q以x0为最大公约数,以y0为最小公倍数.
试求:满足条件的所有可能的两个正整数的个数.
网上许多人的代码是枚举暴力求解,我这里给一个质因数分解加上排列组合的解法
ps:一开始以为x一定是y的因子,导致第一个点过不去,debug了很久。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> bool prime[100000]; int main(){ /* srand(time(0)); int randnum=100000; while(randnum--){ */ long x,y; int num=0; scanf("%ld %ld",&x,&y); /* x=rand()%10000+2; while((y=rand()%10000+2)%x!=0){ }; printf("x=%ld y=%ld\n",x,y); */ if(y%x){ //注意不正规的数据。。。 printf("0"); return 0; } long sum=y/x; int factor[1000],k=0; memset(prime,1,sizeof(prime)); for(int i=2;i*i<=sum;i++) //筛法选出不超过y/x的素数 if(prime[i]) for(int j=i*i;j<=sum;j+=i) prime[j]=0; for(int i=2;i<=sum;i++) //对y/x质因数分解 if(prime[i]&&sum%i==0){ //factor数组里每个数为质因数分解里的每个幂 int p=i; //如20=(2^2)*5 则 factor[0]=4,factor[1]=5; while(sum%(p*i)==0){ p*=i; } factor[k++]=p; } /* for(int i=0;i<k;i++) printf("%d ",factor[i]); printf("\n"); */ int len=1<<k; //利用位运算进行组合运算 对于二进制码 0代表不选择 1代表选择 for(int i=0;i<len;i++){ int j=1; int n=0; long tem=1; while(j<len){ if(i&j) tem*=factor[n]; //按位与运算 求出选择的因子 n++; j=j<<1; } if(sum>tem*tem){ //由于通过质因数分解,每个做法都满足要求,因此只需要选出P>Q的个数 最后乘以2即可 num++; //printf("%d %d\n",x*sum/tem,x*tem); } } printf("%d",(x==y)?1:2*num); //当x==y时 个数只有1个 return 0; } |