《小杨的锻炼》题解

博客背景 

Добрый день! 大家好,我是Zac,太久没更文章了(毕竟假期出去玩了)。

这不是马上要考五级了吗,我回到了新手村,又看了一道我去年做5级的题,突然发现我之前的解法看——不——懂!于是呃我准备再写一版……先来看看题目吧~

题目描述

小杨的班级里共有 n 名同学,每位同学都有各自的锻炼习惯。具体来说,第 i 位同学每隔 ai​ 天就会进行一次锻炼(也就是说,每次锻炼会在上一次锻炼的 ai​ 天后进行)。某一天,班上的 n 名同学恰好都来进行了锻炼。他们对此兴奋不已,想要计算出下一次所有同学都来锻炼,至少要过多少天。但他们不会计算,你能帮帮他们吗?

输入格式

第一行一个整数 n,表示同学的数量。
第二行 n 个用空格隔开的正整数,依次为 a0​,a1​,…,an−1​。

输出格式

输出一个整数,表示下一次所有同学都来锻炼,至少要过多少天。

输入输出样例

输入#1

3
1 2 3

输出#1

6

输入#2

4
2 4 8 16

 输出#2

16

输入#3

4
2 4 6 8

输出#3

24

分析

题目分析

首先,先看题目:“某一天,班上的 n 名同学恰好都来进行了锻炼。他们对此兴奋不已,想要计算出下一次所有同学都来锻炼,至少要过多少天。” 这句话非常清楚地告诉了我们这道题的题意:这道题目的目标是计算多个同学锻炼周期的最小公倍数(LCM),即下一次所有同学再次同一天锻炼所需的最少天数。每个同学的锻炼周期由输入的数组给出。

我们接着分析题目:

  1. 问题转化:题目要求找到所有同学锻炼周期的最小公倍数。当所有同学在同一天锻炼后,下一次共同锻炼的天数即为这些周期的最小公倍数。

  2. 数学基础:两个数的最小公倍数可以通过它们的乘积除以最大公约数(GCD)得到。对于多个数的情况,可以逐个计算累积的LCM。

  3. 算法选择:使用欧几里得算法计算GCD,然后通过逐次计算每两个数的LCM来累积得到所有数的LCM。

思路分析

  1. 初始化LCM:从第一个同学的锻炼周期开始,初始LCM设为第一个数。

  2. 逐次计算:对于后续每个同学的周期,计算当前LCM与该周期数的GCD,然后用这两个数的乘积除以GCD来更新LCM。

  3. 累积结果:最终累积的LCM即为所有同学周期的LCM,即答案。

根据这些,我们直接

上代码:

强迫症版:

#include <iostream>
#include <cmath>
using namespace std;
int f(int a, int b) {
    return b == 0 ? a : f(b, a % b);
}
int main() {
    int n;
    cin >> n;
    int a[n + 1];
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    int sum = a[0];
    for (int i = 1; i < n; i++) {
        int t = sum;
        sum = f(sum, a[i]);
        sum = sum * (t / sum) * (a[i] / sum);
    }
    cout << sum << endl;
    return 0;
}

懒人版:

#include<iostream>
#include<cmath>
using namespace std;
int f(int a,int b){
    return b==0?a:f(b,a%b);
}
int main(){
    int n;
    cin>>n;
    int a[n+1];
    for(int i=0;i<n;i++) cin>>a[i];
    int sum=a[0];
    for(int i=1;i<n;i++){
        int t=sum;
        sum=f(sum,a[i]);
        sum=sum*(t/sum)*(a[i]/sum);
    }
    cout<<sum<<endl;
    return 0;
}

代码解析

  1. 输入处理:读取同学数量n和他们的锻炼周期数组a

  2. 计算GCD:使用递归函数f(即欧几里得算法)计算两个数的GCD。

  3. 计算LCM:遍历数组,依次计算当前LCM与下一个数的LCM,并更新结果。

  4. 输出结果:最终的LCM即为所求天数。

复杂度分析

  • 时间复杂度:O(n log a_max),其中a_max是数组中最大的数。每次计算GCD的时间复杂度为O(log a_max),需要遍历n个数。

  • 空间复杂度:O(n)存储输入数组,递归栈深度不影响整体复杂度。

总结

通过逐次计算每两个数的最小公倍数,并累积结果,可以高效地求解多个数的最小公倍数。使用欧几里得算法计算GCD,保证了算法的高效性。该方案正确处理了所有可能的输入情况,包括大数运算,确保结果正确。对了,点个三连再走呗~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值