[C Language] Optimization of the greatest common divisor and least common multiple algorithm

topic

Title source:Xiao Lele and Euclid_Niuke Topic_Niuke.com (nowcoder.com)

describe

Xiao Lele recently learned in class how to find the greatest common divisor and least common multiple of two positive integers, but he can't find the sum of the greatest common divisor and least common multiple of two positive integers. Please help him solve this problem. .

Enter description:

Each set of inputs contains two positive integers n and m. (1 ≤ n ≤ 109, 1 ≤ m ≤ 109)

Output description:

For each set of inputs, output a positive integer, which is the sum of the greatest common divisor and the least common multiple of n and m.

Example 1

enter:

10 20

Output:

30

Example 2

enter:

15 20

Output:

65

brute force solution

greatest common divisor

What is a divisor? It is a number that can be divisible. A common divisor is a number that is divisible by two numbers. Then the greatest common divisor is the largest number that is divisible by both numbers.

So we might as well think about how to get the greatest common divisor of two numbers?

Suppose the two numbers area,b, then is the common factor necessarily less than or equal to the smaller of the two numbers? Why? Because if your number is larger than any other number, it will not satisfy the divisor condition. Therefore, we can set up a loop to decrement from the smaller of the two numbers until the first divisor is found, then this number is the greatest common divisor

code show as below

long long Max(long long x, long long y) {
    
    
    if(x > y){
    
    
        long long tmp = x;
        x = y;
        y = tmp;
    }
    for(int i = x;i > 1;i++){
    
    
        if(x % i == 0 && y % i == 0){
    
    
            return i;
        }
    }
    return 1;
}

least common multiple

Then we find the least common multiple in the same way. We start from the largest of the two numbers and find them one by one. They are all written in the same way, so I won’t go into details.

long long Min(long long x, long long y) {
    
    
    if(x > y){
    
    
        long long tmp = x;
        x = y;
        y = tmp;
    }
    long long i = y;
    while(!(i % y == 0 && i % x == 0)){
    
    
        i++;
    }
    return i;
}

So if you use the two violent solutions above to sum up and submit the code, you will definitely not be able to pass it, and you will be prompted您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大

In other words, the brute force solution cannot be passed here, so next we have to use some mathematical methods to solve this problem.

Code optimization

Principle explanation

A very well-known algorithm for finding the greatest common divisor is actually used here,euclidean division method

Here we assumea,b is the number we require and at this timea> b, put a/b to get the remainderK1, and put b As the next divisor (a in the next operation)K1 as the next dividend (b in the next operation). Each time a calculation is performed, the last dividend is used as the divisor of this calculation, and the last remainder is used as the dividend until the remainder is 0, then b at this time is the greatest common divisor.

at the timeKn = 0whenKn-1the maximum common number

The proof here is still a bit difficult, and it is not easy to understand. But you can give an example to help understand

The following is a calculation example for K4 = 0

You will find that if we keep bringing back, eventually all the monomials of a and b will appearK3

Then we can implement this algorithm in code

long long Max(long long x, long long y) {
    
    
//先保证x是大于y的
    if(x > y){
    
    
        long long tmp = x;
        x = y;
        y = tmp;
    }
    long long tmp;
    //当余数不为0时,一直辗转
    while(x % y){
    
    
        tmp = x % y;
        x = y;
        y = tmp;
    }
    //此时余数为0,此时的被除数y为最大公约数
    return y;
}

Then we will also use this greatest common divisor to find the least common multiple

If you find the least common multiple of a and b, their greatest common divisor is r, then the formula used Yesa*b/r (Due to the definition of the greatest common divisor and the least common multiple: the product of two integers is equal to the product of their greatest common divisor and the least common multiple)

Then you only need to set the formula to write the final code

long long min = a*b/max;

Code overview

#include <stdio.h>
long long Max(long long x, long long y) {
    
    
    if(x > y){
    
    
        long long tmp = x;
        x = y;
        y = tmp;
    }
    long long tmp;
    while(x % y){
    
    
        tmp = x % y;
        x = y;
        y = tmp;
    }
    return y;
}
int main() {
    
    
    long long a, b;
    while (scanf("%lld %lld", &a, &b) != EOF) {
    
    
        long long max = Max(a, b);
        long long min = a*b/max;
        printf("%lld", max + min);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_42150700/article/details/130072197