ybt1915 最大公约数和最小公倍数问题(NOIP2001普及组第2题)
时空限制 1000ms/128MB
题目描述
输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数
条件:
1.P,Q是正整数
2.要求P,Q以x0为最大公约数,以y0为最小公倍数.
试求:满足条件的所有可能的两个正整数的个数.
输入
二个正整数x0,y0
输出格式
一个数,表示求出满足条件的P,Q的个数
输入样例
3 60
输出样例
4
说明
P,Q有4种 3 60 15 12 12 15 60 3
分析
两个数x,y,它们的最大公约数为gcd,最小公倍数为lcm,那么 x*y=gcd*lcm。
有了这个基础后就可以做了。
代码
法一:枚举
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int x,y,ans=0;
cin>>x>>y;
if (x==y) { cout<<1<<endl; return 0; }
else if (x>y || y%x) { cout<<0<<endl; return 0; }
long long tp=x*y,t=sqrt(x*y);
for (int i=x,m,n,r; i<=t; ++i){ //枚举其中一个数i
if (tp%i) continue; //另外一个数tp/i
m=tp/i; n=i; r=m%n;
while (r){ //辗转相除法求最大公约数
m=n; n=r; r=m%n;
}
if (n==x) ans++; //i与tp/i最大公约数是否为x
}
cout<<ans*2<<endl;
return 0;
}
题目要求最大公约数(gcd)为3,最小公倍数(lcm)为60的两个数p、q的组数,两个数都去掉gcd后,即样例中的3、60变为1、20。
这样即可变为求gcd为1,lcm为20的两个数p、q的组数,即找两个互质的数,他们的乘积为20。
那么可以对20进行质因数分解,得:2、2、5。盯住其中一个数,从质因数中选择。由于两个数要求互质,所以相同的质因数要合并,得到:4、5。
选法有2^2=4种:1,4,5,20。对应的四组答案即:1-20,4-5,5-4,20-1。
乘以gcd得到原来题目答案:3-60,12-15,15-12,60-3。
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int x,y,ans=0;
cin>>x>>y;
if (x==y) { cout<<1<<endl; return 0; }
else if (x>y || y%x) { cout<<0<<endl; return 0; }
y /= x; //除以最大公约数
for (int i=2; i<=y; ++i) //质因数分解
if (y%i==0){
ans++;
while (y%i==0) y/=i;
}
cout<<pow(2.0,ans)<<endl;
return 0;
}