已知最大公约和最小公倍数,求可能的解的组数

来源:互联网 发布:淘宝轮番图片尺寸 编辑:程序博客网 时间:2024/05/09 00:01

算法刷题记录(已知最大公约和最小公倍数,求可能的解的组数)

之第1012题

题目描述:

输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数条件:  1.P,Q是正整数2.要求P,Q以x0为最大公约数,以y0为最小公倍数.试求:满足条件的所有可能的两个正整数的个数.

题解:

#include <iostream>using namespace std;int gcd(int a,int b){           //计算两个数的最大公约数    return (b==0)?a:gcd(b,a%b);}int main(){    int a,b;    int count=0;    cin>>a>>b;    if(b%a==0){                   //判断输入的数是否为整除关系        int c=b/a;                //如果不是整除关系则一定没有结果        for(int x=1;x<=c;x++){    //遍历一直到c            if(c%x==0) {          //取c的因数                int m=x*a;        //计算第一因数 m                int n=c/x*a;      //计算第二个因数 n                if(a==gcd(m,n)){  //判断m和n能否取到以a为最大公约数                    count++;      //是则计数加1                }            }        }     }else count=0;                //不能整除,一定是0;    cout<<count<<endl;    return 0;}

思路:

在已知最大公约和最小公倍数的情况下去计算一共有多少组可能的值使得的输入能够成立。首先很熟悉计算最大公约和最小公倍数的算法,但是如果直接两重for遍历进行判断和比较的话,时间复杂度就会大大增加,在进行如题的比较大的数据时,一定是通过不了的。所以要用数学的思维去简化整个问题,降低计算的复杂度。首先考虑:假设 m,n的最大公约数为x0,最小公倍数数y0;* 则   m×n=x0×y0;* 设c为y0整除x0的值,那么m和n的取值中最大为m*c,最小为m*1;* 即先求解所有c的因数,从中找所有可能的组合* 注意到在这个地方,所有c的因数一定是两两相对的,一个是m=x0*c1,,另一个一定是n=x0*c2;* 同时可以看出c1*c2=c的,故遍历出一个m即可计算n;* 再判断m,n的最大公约数是不是x0,如果是,那么就表明m,n是一组,则记录下来* 这样当c的所有因数遍历完,则完成了所有可能m,n的选取* 同时要注意的是当x0与y0不能整除时,那么肯定找不到适合的m,n;
0 0