洛谷P1029 [NOIP 2001 普及组]最大公约数和最小公倍数问题

题目链接:

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字,不信可自测。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值