最大公约数和最小公倍数问题(luogu 1029)

 题目描述

输入 2 个正整数 x0,y(2x0<100000,2y0<=1000000),求出满足下列条件的P,Q的个数

条件:

  1.  P,Q 是正整数
  2. 要求P,Q 以x为最大公约数,以y0为最小公倍数

试求:满足条件的所有可能的 2 个正整数的个数

 

输入格式:

2 个正整数x0,y0

输出格式:

1 个数,表示求出满足条件的 P,Q 的个数

 

输入样例          输出样例

  3  60            4 

 

说明

1、3,60
2、15,12
3、12,15
4、60,3


初学数论,兴奋不已……

 解析:

因为:x_0 为P,Q 的最大公约数

所以:P = x_0*k1  Q=x_0*k2 (k1,k2 互质)

因为:y_0 为P,Q 的最小公倍数

所以:k1*k2*x_0=y_0  ==》 y0 / x0 = k1 * k2

 

因此我们只用枚举 k1 ,求出 k2 ,再判断 k1 , k2 是否互质 ,就可以啦

我们枚举的范围肯定不能超过y0,从样例可以看出,从 sk 开方的位置分为的两半,左右是 对称的,所以我们只需要求出左边一半,乘 2 就好啦 

 

一个易懂代码

#include<stdio.h>
#include<math.h>

int gcd(int x,int y)
{
    if(y==0) return x;
    else return gcd(y,x%y);
}

int main()
{
    int x_0,y_0;
    scanf("%d%d",&x_0,&y_0);
    
    if(y_0%x_0!=0) {
        printf("0");
        return 0;
    } 
    
    int ans=0;
    int sk=y_0/x_0;
    for(int i=1;i<=sqrt(sk);++i)
    {
        if(sk%i==0) {
            int k1=i,k2=sk/i;
            if(gcd(k1,k2)==1) {
                ans+=2;
            }
        }
    }
    printf("%d",ans);
    
    return 0;
} 

 

一个浓缩代码(我都看不懂QWQ)

#include<stdio.h>
#include<math.h>
using namespace std;

int gcd(int x,int y)// x:被除数     y:除数 
{
    if(y==0) return x;
    return gcd(y,x%y);// gcd(除数,余数)
}

int main()
{
    int n,m,ans=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=sqrt(m*n);++i)
    {
        if((m*n)%i==0 && gcd((m*n)/i,i)==n) ans++;
    }
    printf("%d",ans*2);
    return 0;
}

 

posted @ 2018-08-12 12:53  qseer  阅读(192)  评论(0编辑  收藏  举报