题目链接:
P1029 最大公约数和最小公倍数问题
题目描述
输入二个正整数x0,y0,求出满足下列条件的P,Q的个数
条件:
-
P,Q是正整数
-
要求P,Q以x0为最大公约数,以y0为最小公倍数
试求:
满足条件的所有可能的两个正整数的个数
输入格式
两个正整数x0和y0
输出格式
输出满足条件的所有可能的两个正整数的个数。
样例输入
3 60
样例输出
4
样例解释
此时的P Q分别为:
3 60
15 12
12 15
60 3
所以,满足条件的所有可能的两个正整数的个数共4种
数据规模
对于全部的数据2≤x0≤1000000,2≤y0≤1000000
思路:
首先,我们很容易发现一个规律:两个数的乘积等于它们的最大公因数和最小公倍数的乘积
证明:
设这两个数分别为A,B,它们的最大公因数为C,再设A/C=a,B/C=b(其中a,b互质,如果不互质的话,A和B还有更大的公因数)。所以,A和B的最小公倍数就是a*b*C(如果不懂,建议去网上自己找,我已无能为力)。
那么,A*B就等于a*C*b*C,它们的最小公倍数乘最大公因数就是a*b*C*C,很明显,这两个式子是一样的,证毕。
知道了这个以后,我们就可以开始写代码了,先定义gcd(最大公约数英文缩写,全称为Greatest Common Divisor,常缩写为gcd)函数,然后根据上面的定理,定义一个lcm(最小公倍数英文缩写,全称为Least common multiple,常缩写为lcm)函数,接着枚举x0~y0的数,遇到满足条件的就cnt++。
AC代码:
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b)
{
return a%b==0?b:gcd(b,a%b);
}
long long lcm(long long a,long long b)
{
return a/gcd(a,b)*b;
}
int main()
{
long long a,b,c,cnt=0;
cin >> a >> b;
for(int i=a;i<=b;i++)//从a到b就可以啦
{
c=a*b/i;//只有这样才能保证有解,不然要是连乘积等于最大公因数和最小公倍数乘积都不满足,根本不用判断下面了,绝对错的
if(gcd(c,i)==a&&lcm(c,i)==b)
{
cnt++;
}
}
cout<<cnt;
return 0;
}
今天的博客就到这里了,(套句子)作者创作不易,请勿抄袭,转载请标明出处,谢谢!当然,如果觉得代码还行的话,建议点个关注点个赞,顺便收藏一下,谢谢!【笔芯】
当然,也鼓励大家评论,可以指出作者的不足,我看到后(我每天都会看一看的)会回复,也会努力改正。
最后的最后,给大家整个活吧:本博客共个1109字,不信可自测。