求 n 个数的最小公倍数(详解版)

你的好朋友小明最近在学习最小公倍数的知识,他妈妈给他出了100题,每一题都有n(2≤n≤20)个数,要小明求出这n个数的最小公倍数。小明现在想快点出去玩,于是想到会编程的你,能否设计一个程序,让他输入题目n个数就可以得到答案?快来帮帮小明吧!

输入格式

第一行一个整数 n (2≤n≤20)。

第二行 n 个整数。

输出格式

一个整数,表示最小公倍数,数据保证答案不超过int范围。

输出时每行末尾的多余空格,不影响答案正确性

输入/输出例子1

输入:

5

2 4 6 8 10

输出:

120

浅说:这道题如果是道数学的话比较容易,但代码实现的话不容易想到,下面对这道题的思路和样例进行了详细地解析,方便大家更好的理解~ 完整代码在最下面~

核心代码片段

for(int j = n - 1; j > 0; j--) {
    for(int i = a[j - 1]; i > 0; i--) {
        if(a[j] % i == 0 && a[j - 1] % i == 0) {
            a[j - 1] = a[j] * a[j - 1] / i;
            break;
        }
    }
}

代码的作用

这段代码的目的是计算数组中所有数的最小公倍数(LCM)。它的核心思想是:

  1. 从数组的末尾开始,依次计算相邻两个数的最小公倍数。

  2. 将计算得到的最小公倍数赋值给前一个数,然后继续向前计算。

  3. 最终,数组的第一个元素(a[0])就是所有数的最小公倍数。

代码的详细逻辑

for(int j = n - 1; j > 0; j--)
  • 从数组的最后一个元素开始,向前遍历到第二个元素(j 从 n-1 到 1)。
  • 每次循环处理 a[j] 和 a[j-1] 两个数。
for(int i = a[j - 1]; i > 0; i--)
  • 从 a[j-1] 开始递减,寻找 a[j] 和 a[j-1] 的最大公约数(GCD)。
  • i 是可能的公约数,从大到小遍历。
if(a[j] % i == 0 && a[j - 1] % i == 0)
  • 如果 i 能同时整除 a[j] 和 a[j-1],则 i 是它们的公约数。

  • 由于 i 是从大到小遍历的,第一个满足条件的 i 就是最大公约数(GCD)。

a[j - 1] = a[j] * a[j - 1] / i;
  • 利用公式 LCM(a,b) = GCD(a,b) / a×b​ 计算最小公倍数。

  • 将计算得到的最小公倍数赋值给 a[j-1]

break;
  • 找到最大公约数并计算最小公倍数后,跳出内层循环,继续处理下一对数。

举例说明

 假设输入数组为 a = [2, 4, 6, 8, 10],n = 5。

第一次外层循环(j = 4):
  • 当前数:a[j] = 10a[j-1] = 8

  • 内层循环从 i = 8 开始递减:

    • i = 8:检查 10 % 8 == 2,不满足。

    • i = 7:检查 10 % 7 == 3,不满足。

    • i = 6:检查 10 % 6 == 4,不满足。

    • i = 5:检查 10 % 5 == 0 且 8 % 5 == 3,不满足。

    • i = 4:检查 10 % 4 == 2,不满足。

    • i = 3:检查 10 % 3 == 1,不满足。

    • i = 2:检查 10 % 2 == 0 且 8 % 2 == 0,满足。

      • 计算最小公倍数:a[j-1] = (10 * 8) / 2 = 40

      • 更新数组:a = [2, 4, 6, 40, 10]

      • 跳出内层循环。

第二次外层循环(j = 3):
  • 当前数:a[j] = 40a[j-1] = 6

  • 内层循环从 i = 6 开始递减:

    • i = 6:检查 40 % 6 == 4,不满足。

    • i = 5:检查 40 % 5 == 0 且 6 % 5 == 1,不满足。

    • i = 4:检查 40 % 4 == 0 且 6 % 4 == 2,不满足。

    • i = 3:检查 40 % 3 == 1,不满足。

    • i = 2:检查 40 % 2 == 0 且 6 % 2 == 0,满足。

      • 计算最小公倍数:a[j-1] = (40 * 6) / 2 = 120

      • 更新数组:a = [2, 4, 120, 40, 10]

      • 跳出内层循环。

第三次外层循环(j = 2):
  • 当前数:a[j] = 120a[j-1] = 4

  • 内层循环从 i = 4 开始递减:

    • i = 4:检查 120 % 4 == 0 且 4 % 4 == 0,满足。

      • 计算最小公倍数:a[j-1] = (120 * 4) / 4 = 120

      • 更新数组:a = [2, 120, 120, 40, 10]

      • 跳出内层循环

第四次外层循环(j = 1):
  • 当前数:a[j] = 120a[j-1] = 2

  • 内层循环从 i = 2 开始递减:

    • i = 2:检查 120 % 2 == 0 且 2 % 2 == 0,满足。

      • 计算最小公倍数:a[j-1] = (120 * 2) / 2 = 120

      • 更新数组:a = [120, 120, 120, 40, 10]

      • 跳出内层循环。

最终结果
  • a[0] = 120,输出 120

完整代码

#include<bits/stdc++.h>
using namespace std;
int n,a[25];
int main(){
    cin>>n;
    for(int i = 0;i < n;i++){
        cin>>a[i];
    }
    sort(a,a + n);
    for(int i = n - 1;i > 0;i--){
        for(int j = a[i - 1];j > 0;j--){
            if(a[i] % j == 0 && a[i - 1] % j == 0){
                a[i - 1] = a[i] * a[i - 1] / j;   
                break;
            }
        }
    }
    cout<<a[0];
    return 0;
}

创造不易,如果对您有所帮助,请一键三连哦~你的支持是我继续创造的动力源泉~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小假

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值