题目:
B3941 [GESP样题 五级] 小杨的锻炼 - 洛谷 | 计算机科学教育新生态
题目描述
小杨的班级里共有 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
说明/提示
样例 1 解释
第一位同学每天都锻炼;第二位同学每 2 天锻炼一次;第三位同学每 3 天锻炼一次。因此,6 天之后,三位同学都会进行锻炼。在此之前,第二位同学只会在第 2, 4 天进行锻炼,第三位同学只会在第 3 天进行锻炼,他们都无法相遇。
样例 2 解释
第四位同学每 16 天锻炼一次,而 16 天后也恰好是前三位同学锻炼的日子。
数据规模与约定
- 对 20% 的数据,n=2。
- 对 50% 的数据,n=4。
- 对 100% 的数据,2≤n≤10,1≤ai≤50。
思路:
这个题目很明显的就是告诉我们求最小公倍数。所以我们使用辗转相除法(欧几里得算法)求解最大公约/最小公倍数。注意,第一次可以用1和第一次出现的数进行求最小公倍数,因为1和非0数n的最大公约数是1,最小公倍数都是n.
代码如下:
#include<iostream>
using namespace std;
typedef long long ll;
const ll N = 1e6;
ll n;
ll m = 1;;
void gcd(ll x)
{
ll a,b,temp;
a = m;
b = x;
while(b)
{
temp = a % b;
a = b;
b = temp;
}
//a为最大公约数
// cout <<" 最小公倍数:"<< m*x/a << endl;
// cout <<"最大公约数:" << a << endl;
m = m*x/a;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
ll t;
for(int i = 1 ; i <= n ; i++)
{
cin >> t;
gcd(t);
}
cout << m;
return 0;
}