DAY-1 | 迭乘法、辗转相除法、试除法:最大公约数与最小公倍数问题

这里是C语言刷题日志,整理了博主本人平时做练习遇到的问题以及相关的总结。不定时对文章内容更新优化,持续维护。


目录

一、题干

二、题解

1. 辗转相除法

2. 试除法

三、方法总结

1. 辗转相除法最大公约数

2. 迭乘法求最小公倍数

3. 试除法求最大公约数与最小公倍数


一、题干

牛客网链接

BC115 小乐乐与欧几里得https://www.nowcoder.com/practice/da13e0cf321e4df9acd0fdf0a433cbb0?tpId=107&&tqId=33396&rp=1&ru=/ta/beginner-programmers&qru=/ta/beginner-programmers/question-ranking

二、题解

1. 辗转相除法

辗转相除法可求出两数的最大公约数,再由公式 最小公倍数 = 两数之积 / 最大公约数 求出最小公倍数。

//辗转相除法求最大公约数、最小公倍数

int main()
{
    long long n = 0;
    long long m = 0;
    //输入两个数
    scanf("%lld %lld", &n, &m); 
 
    /*因为求最大公约数和最小公倍数都需要用到m、n,且辗转相除的过程会改编n、m的值,
    故再创建两个变量n2、m2,把m和n的值拷贝一份再做运算*/
    long long m2 = m;
    long long n2 = n;

    long long r = 0;

    //最大公约数
    while (r = n2 % m2)
    {
        n2 = m2;
        m2 = r;    //注意:m2才是所求的最大公约数的结果,而不是r
    }

    //最小公倍数 == m*n/最大公约数
    printf("%lld", m * n / m2 + m2);    //直接求最大公约数和最小公倍数的和

    return 0;
}

注意:不需要比较m和n两数的大小再计算。


2. 试除法

设置变量max代表最大公约数,变量min代表最小公倍数。

核心思路为,初始化max与输入的两数中更小的数相等;初始化min与输入两数中更大的数相等。

由最大公约数的规则,max能同时被两数除尽,且为满足条件的数中的最大值。这样一来,只需要让max不断自减,当max自减到恰好可以同时被两数除尽。这时候的max就是最大公约数。

同样,由最小公倍数的规则,min是两数的倍数,即min分别除以两数都能除尽,且为满足条件的最小值。这只需让min不断自增,一个一个向上走,直到恰好满足条件即可。

根据这样的思路,我们能总结出以下的算法:

int main()
{
    int n = 0;
    int m = 0;
    scanf("%d %d", &n ,&m);
    int max = (n>m?m:n);//假设最大公约数,是n和m的较小值
    
    //求最大公约数
    while(1)
    {
        if(n % max == 0 && m % max == 0)
        {
            break;
        }
        max--;    //max从m与n中的较小值开始不断自减,挨个检查是否满足条件。一旦满足就跳出
    }

    int min = (n>m?n:m);//假设最小公倍数,是n和m的较大值

    //求最小公倍数
    while(1)
    {
        if(min % n == 0 && min % m == 0)
            break;
        min++;    //思路同上,挨个检查
    }

    printf("%d\n", max+min);    //回到题干,题干要求的是求min和max的和

    return 0;
}

三、方法总结

1. 辗转相除法最大公约数

虽然上面介绍了用辗转相除法求最小公倍数的操作,但本质上辗转相除法在此是求最大公约数的。因此我们把它拿出来单独强调。

//辗转相除法求最大公约数

int main(){

    int m,n;
    int tmp = 0;
    scanf("%d %d",m,n);

    while(tmp = m % n){
        m = n;
        n = tmp;
    }
    
    printf(最大公约数是:"%d",n);    //注意,最后的n(也就是模数,右边的那个数)才是要求的最大公约数
}

 最小公倍数 == 两数相乘再除以其最大公约数。


2. 迭乘法求最小公倍数

迭乘法的思路是这样的:

由公倍数的定义出发,如果一个数k是a和b的公倍数,那么k可以表示成 a*i 或 b*j 。转换成编程语言表达,即:

//若k为a和b的最小公倍数,则有:

k == a*i
k == b*j    

//也就是说,当(a*i) % b == 0时,k是最小公倍数

编写成完整代码,即: 

//迭乘法求最小公倍数

int main(){
    int a = 0;
    int b = 0;
    scanf("%d %d", &a, &b);    //输入两个数
  
    int i = 1;
    while((a*i) % b != 0){
        i++;
    }

    printf("最小公倍数是:%d\n", a * i);    //最小公倍数:i*a

    return 0;
}

3. 试除法求最大公约数与最小公倍数

和上面提到过的试除法思路相同,就是挨个试。比如要求20和30的最大公约数,那就从20开始挨个往下检查,看看19能不能同时被20和30整除;19不符合条件再往下看18、17、16…直到找到符合条件的。求最小公倍数也一样,就是挨个往上试,总能找到满足条件的,再输出就好了。

确实,试除法的效率相对较低。

//最大公约数
int main()
{
    int n = 0;
    int m = 0;
    scanf("%d %d", &n ,&m);
    int max = (n>m?m:n);//假设最大公约数,是n和m的较小值
    
    //求最大公约数
    while(1)
    {
        if(n % max == 0 && m % max == 0)
        {
            break;
        }
        max--;    //max从m与n中的较小值开始不断自减,挨个检查是否满足条件。一旦满足就跳出
    }

    printf("最大公约数是 %d",max);

    return 0;
}
 //最小公倍数
int main(){
   
    int n = 0;
    int m = 0;
    scanf("%d %d", &n ,&m);
    
    int min = (n>m?n:m);

    //求最小公倍数
    while(1)
    {
        if(min % n == 0 && min % m == 0)
            break;
        min++;
    }

    printf("最小公倍数是 %d", min); 
    return 0;
}
  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值