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

简介: 这段内容是一个关于计算两个数的最大公约数(Greatest Common Divisor, GCD)和最小公倍数(Least Common Multiple, LCM)的编程题目说明,包括题干、题解和方法总结。其中提到了两种方法:辗转相除法和试除法。辗转相除法通过不断用较大数除以较小数直到余数为零来求最大公约数,然后利用两数乘积除以最大公约数得到最小公倍数。试除法则是通过循环尝试两数的倍数是否同时能被两数整除来求解。在方法总结部分,还介绍了迭乘法求最小公倍数的方法。

一、题干


牛客网链接


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*ib*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;
}



相关文章
|
1月前
|
算法
求最大公约数和最小公倍数的算法
求最大公约数和最小公倍数的算法
32 0
|
19天前
|
移动开发 算法
最大公约数和最小公倍数
【6月更文挑战第8天】最大公约数和最小公倍数。
25 9
|
14天前
每日一数——最大公约数与最小公倍数
每日一数——最大公约数与最小公倍数
|
1月前
|
算法
辗转相除法求最大公约数
辗转相除法求最大公约数
|
1月前
|
算法
详解最大公约数和最小公倍数
详解最大公约数和最小公倍数
|
11月前
AcWing 869. 试除法求约数
AcWing 869. 试除法求约数
|
1月前
|
人工智能 Java C++
试除法求约数
试除法求约数
24 0
|
10月前
|
算法 C语言 C++
【数论】试除法判断质数,分解质因数,筛质数
将定义进行模拟,若整除了除1与其自身的另外的数,则为质数
81 0
|
人工智能 BI
求最大公约数和最小公倍数
求最大公约数和最小公倍数
67 0
|
算法
求最大公约数和最小公倍数的几种算法
求最大公约数和最小公倍数的几种算法
97 0