您的位置:首页 > 其它

最大公约数和最小公倍数问题

2015-10-24 15:55 375 查看
题目背景
NOIP2001 普及组
题目描述
输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数
条件:
1.P,A是正整数
2.要求P,Q以x0为最大公约数,以y0为最小公倍数.
试求:满足条件的所有可能的两个正整数的个数.


为了响应勤俭节约的号召,我就不描述题目了。

这是一道很简单的题,没错。然而在我研究gcd和lcm之前,是完全不会。。。好吧好吧,现在研究会了就行了。

这道题就是,如果暴力求解,就会TLE

首先要知道公式lcm(a,b)=a*b/gcd(a,b),(具体到下方讨论)然后就可以根据一个值求另一个了。只需要枚举i,不需要枚举j。然而还可以再优化,也就是,i一定是gcd的倍数,i可以一次性加上gcd。加完之后,需要判断是否可以使用这个i。可以的话就让tot+1

#include<iostream>
using namespace std;
inline int gcd(int a,int b){     //求gcd的算法。inline是用来加速的
if(b==0)return a;
return gcd(b,a%b);
}
int main(){
int n,m,tot=0;
cin>>n>>m;                  //m是lcm,n是gcd
for(int i=n;i<=m;i+=n){     //枚举i
if(m%i==0){             //如果lcm根本就不是i的倍数,也就不用求了
int j=(n*m)/i;      //根据上面那个公式推出的求j公式
if(gcd(i,j)==n)tot++;  //即使有j,i和j也不一定会gcd给出的m
}
}
cout<<tot;
}


而lcm(a,b)=a*b/gcd(a,b)呢,就需要以下证明

a的质因数集:{a0,a1……an}

b的质因数集:{b0,b1……bn}

存在am1=bn1,am2=bn2……

所以gcd(a,b)=am1*am2……

lcm(a,b)=a*b/(am1……)出去两个集合相同的元素,也就是gcd(a,b)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: