五十九、如何求N个数的最大公约数和最小公倍数

215 阅读4分钟

@Author:Runsen

编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化。 ---- Runsen

上次介绍了短除法的因式分解,下面正式进入求解:两个及以上个数的最大公约数与最小公倍数

基本要求: 求N个数的最大公约数和最小公倍数。用C或C++或java或python语言实现程序解决问题。

比如:输入三个数,分别是12 14 18,最后程序输出最大公约数2和最小公倍数336。

12 14 16
2
336

此题是蓝桥杯的一题难度偏上的算法题,在之前使用的是短除法,但是短除法求解最大公约数和最小公倍数的公因数都存在一定的困难。

在此前,之前介绍过四种方法,分别是辗转相除法,更相减损术,暴力法和短除法。

个人推荐辗转相除法。辗转相除法是求最大公约数的一种最简单方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。而最小公倍数是这两个数的乘积再除以最大公约数。

在求N个数的最大公约数,可以直接利用前两个数的最大公约数和下一个数进行求解,直到得出最后的结果。

在求N个数的最小公倍数,可以直接利用前两个数的最小公倍数和下一个数进行求解,直到得出最后的结果。

下面求出N个数的最小公倍数和最大公约数,给出具体代码如下。

'''
@Author: Runsen
@WeChat:RunsenLiu 
@微信公众号: Python之王
@CSDN: https://blog.csdn.net/weixin_44510615
@Github: https://github.com/MaoliRUNsen
@Date: 2020/12/9
'''
def func1(nums):  # n个数最大公约数
    a = nums[0]
    for i in range(1, len(nums)):
        b = nums[i]
        while b:  # 辗转相除法
            a, b  = b,a % b
    return a

def func2(nums): # n个数最小公倍数
    # 用辗转相除法遍历 需要和两个数最小公倍数和下一个数查找
    i = nums[0]
    for idx in range(1, len(nums)):
        j = nums[idx]
        # 需要对i 和j 进行变量保存 ,来求最小公倍数
        b = i if i < j else j  # i,j  中较小那个值
        a = i if i > j else j  # i, j  中较大那个值
        r = b  # a除以b的余数
        while r:
            r = a % b
            if r != 0:
               a = b
               b = r
        i = i*j/b  # 两个数的最小公倍数
    return int(i)

s = input().strip(' ').split(' ')
nums = [int(i) for i in s]
print(func1(nums))
print(func2(nums))


12 14 16
2
336
24 28 32
4
672
20 25 30 45
5
900

最近,我在牛客发现有一种非常煞笔,但又不得不佩服的方法,既然给出了数,那我为什么不从一开始到无穷大遍历,如果存在一个数满足所有的条件,虽然时间复杂度很高,但这种笨办法往往是最好的解法。

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author Runsen
 * @date 2020/12/9 13:18
 */
public class SOLVE {
    public static void main(String[] args) {
        while (true) {
            Scanner scan = new Scanner(System.in);
            System.out.println("您想输入几位数:");
            String st = scan.nextLine();
            int a3 = Integer.parseInt(st);
            try {
                System.out.println("请输入几位整数:");
                String s = scan.nextLine();
                String[] s1 = s.split(" ");
                if (s1.length != a3) throw new Exception();
                int[] a = new int[s1.length];
                for (int j = 0; j < s1.length; j++) {
                    a[j] = Integer.parseInt(s1[j]);
                }
                int result1 = 0; //最大公约数
                int result2 = 0; //最小公倍数
                for (int i = 1; i < Integer.MAX_VALUE; i++) {
                    int n = a.length;
                    while (n > 0) {
                        int count = 0;
                        for (int x : a) {
                            if (x % i != 0) {
                                break;
                            } else {
                                count++;
                            }
                            if (count == a.length) {
                                result1 = i;
                                break;
                            }
                        }

                        for (int x : a) {
                            if (i % x != 0) {
                                break;
                            } else {
                                count++;
                            }
                            if (count == a.length) {
                                result2 = i;
                                break;
                            }
                        }

                        n--;
                    }

                    if (result1 > 0 & result2 > 0) {
                        System.out.println(Arrays.toString(a) + "的最大公约数为:" + result1);
                        System.out.println(Arrays.toString(a) + "的最小公倍数为:" + result2);
                        break;
                    }

                }
            } catch (Exception e) {
                System.out.println("输入无效");
            }

        }
    }
}


您想输入几位数:
3
请输入几位整数:
25 20 30
[25, 20, 30]的最大公约数为:5
[25, 20, 30]的最小公倍数为:300
您想输入几位数:
3
请输入几位整数:
24 28 32
[24, 28, 32]的最大公约数为:4
[24, 28, 32]的最小公倍数为:672

如果能把蓝桥杯此题基础又很多人不会的AC,基本能够PASS一半人。

接下来轻松一下。关于编程,大学里学过 C 但没有学到指针就结课了,之后自学过 Java 和 Python ,个人不会C++。至于只会Python能不能找到工作,我没经验,不敢说,但在拉勾,BOSS,牛客招聘真的没见到几个招Python后端Django的。

本文已收录 GitHub,传送门~ ,里面更有大厂面试完整考点,欢迎 Star。