A1131. 最大公约数和最小公倍数问题(Tsinsen)

来源:互联网 发布:mac怎么切换输入法拼写 编辑:程序博客网 时间:2024/05/16 10:04

题目:

输入二个正整数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 91011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
#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;}

原创粉丝点击