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

来源:互联网 发布:2017网络流行语汇总 编辑:程序博客网 时间:2024/05/21 22:58
题目背景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)

0 0