洛谷B3941 [GESP样题 五级] 小杨的锻炼

原理

该程序通过迭代计算相邻元素的最小公倍数(LCM)​,逐步将数组中的元素合并,最终得到整个数组的最小公倍数。具体原理如下:

  1. LCM 的传递性
    LCM 满足结合律,即 lcm(a, b, c) = lcm(lcm(a, b), c)。程序通过逐个合并相邻元素,最终得到整个数组的 LCM。
  2. 逐步覆盖数组
    每次计算当前元素与下一个元素的 LCM,并将结果覆盖到下一个元素的位置。最终最后一个元素即为整个数组的 LCM。

步骤

  1. 输入处理
    读取整数 n 和包含 n 个元素的数组 A
  2. 迭代计算 LCM
    从第一个元素开始,依次计算当前元素与下一个元素的 LCM,并将结果覆盖到下一个元素的位置。
  3. 输出结果
    数组的最后一个元素即为整个数组的 LCM。

图示法示例(输入:[2, 3, 4]

初始数组: [2, 3, 4]
步骤1: 计算 lcm(2,3)=6 → 数组变为 [2, 6, 4]
步骤2: 计算 lcm(6,4)=12 → 数组变为 [2, 6, 12]
输出: 12

代码程序及关键行注释

#include <iostream>
#include <vector>

using namespace std;

// 计算最大公约数(GCD)
int gcd(int a, int b) {
    while (b != 0) {
        int temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

// 计算最小公倍数(LCM)
int lcm(int a, int b) {
    if (a == 0 || b == 0) return 0; // 处理边界情况
    return (a / gcd(a, b)) * b;     // 公式:LCM(a,b) = a*b / GCD(a,b)
}

int main() {
    int n;
    cin >> n;
    vector<int> A(n);
    for (int i = 0; i < n; i++) {
        cin >> A[i];
    }
    
    int i = 0;
    while (i < n - 1) { // 遍历到倒数第二个元素
        A[i + 1] = lcm(A[i], A[i + 1]); // 将后一个元素替换为当前LCM
        i++;
    }
    
    cout << A[n - 1] << endl; // 输出最后一个元素(即最终LCM)
    return 0;
}

时间复杂度

  1. 单次 LCM 计算
    每次 LCM 计算的时间复杂度为 O(log(min(a, b))),其中 a 和 b 为参与计算的两个数。
  2. 总时间复杂度
    数组需要遍历 n-1 次,总时间复杂度为 O(n * log M),其中 M 为数组中的最大值。

总结

  1. 核心思想
    利用 LCM 的结合律,通过迭代合并相邻元素,逐步计算整个数组的 LCM。
  2. 优点
    代码简洁,逻辑清晰,适用于小规模数据。
  3. 潜在问题
    若数组元素较大或较多,LCM 值可能超出整数范围(需根据题目约束判断)。
  4. 适用场景
    适用于输入规模较小且数值范围可控的场景。若数值过大,需改用大数处理或优化算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值