Description
In a strange planet there are n races. They are completely different as well as their food habits. Each race has a food-eating period. That means the ithrace eats after every xi de-sec (de-sec is the unit they use for counting time and it is used for both singular and plural). And at that particular de-sec they pass the whole day eating.
The planet declared the de-sec as 'Eid' in which all the races eat together.
Now given the eating period for every race you have to find the number of de-sec between two consecutive Eids.
Input
Input starts with an integer T (≤ 225), denoting the number of test cases.
Each case of input will contain an integer n (2 ≤ n ≤ 1000) in a single line. The next line will contain n integers separated by spaces. The ith integer of this line will denote the eating period for the ith race. These integers will be between 1 and 10000.
Output
For each case of input you should print a line containing the case number and the number of de-sec between two consecutive Eids. Check the sample input and output for more details. The result can be big. So, use big integer calculations.
Sample Input
2
3
2 20 10
4
5 6 30 60
Sample Output
Case 1: 20
Case 2: 60
题意:给你n个数,求着n个数的最小公倍数
n<1000 且 1< 每个数 <10000
直接gcd每个数然后相乘肯定会爆longlong
所以换一下思路
用唯一分解定理求出每个数的质因数及个数,存储每个质因数的最多个数
最后再高精全部乘起来就行了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#include <string>
#include <sstream>
#include <map>
#include <set>
#define pi acos(-1.0)
#define LL long long
#define ULL unsigned long long
#define inf 0x3f3f3f3f
#define INF 1e18
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define debug(a) printf("---%d---\n", a)
#define mem0(a) memset(a, 0, sizeof(a))
#define memi(a) memset(a, inf, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
#define input1(a) scanf("%d", &a)
#define input2(a,b) scanf("%d %d", &a, &b)
#define input3(a,b,c) scanf("%d %d %d", &a, &b, &c)
using namespace std;
typedef pair<int, int> P;
const double eps = 1e-10;
const int maxn = 1e6 + 5;
const int N = 1e4 + 5;
const int mod = 1e8;
int prime[maxn], vis[maxn], pt;
int cnt[maxn];
int ans[N], high;
void chart()
{
memset(vis, 0, sizeof(vis));
vis[1] = 1;
pt = 0;
for (int i = 2; i < N; i++){
if (vis[i]) continue;
prime[++pt] = i;
for (int j = 2; j * i < N; j++)
vis[j * i] = 1;
}
}
void solve(int x)
{
// int i;
// for (i = 1; i <= pt && prime[i]*prime[i] <= x; i++){ // 用prime[i]*prime[i] <= x 优化
// int tmp = 0;
// while (x % prime[i] == 0){
// x /= prime[i];
// tmp++;
// }
// cnt[i] = max(cnt[i], tmp);
// high = max(high, i);
// }
// if (x > 1){
// for (; i <= pt; i++)
// if (prime[i] == x) {
// cnt[i] = max(cnt[i], 1);
// high = max(high, i);
// break;
// }
// }
for (int i = 1; i <= pt; i++){ // 唯一分解定理
int tmp = 0;
while (x % prime[i] == 0){
x /= prime[i];
tmp++;
}
cnt[i] = max(cnt[i], tmp);
high = max(high, i);
if (x == 1) break;
}
}
int main(void)
{
// freopen("in.txt","r", stdin);
chart();
int T, n, x, cas = 0;
cin >> T;
while (T--)
{
cin >> n;
memset(cnt, 0, sizeof(cnt));
high = -1;
for (int i = 1; i <= n; i++){
cin >> x;
solve(x);
}
memset(ans, 0, sizeof(ans));
ans[0] = 1;
for (int i = 1; i <= high; i++){
if (cnt[i] == 0) continue;
int num = pow(prime[i], cnt[i]);
for (int j = 0; j < 5002; j++) ans[j] *= num;
for (int j = 0; j < 5002; j++){
ans[j+1] += ans[j]/10;
ans[j] %= 10;
}
}
int dex = 5001;
while (ans[dex] == 0) dex--;
printf("Case %d: ", ++cas);
for (int i = dex; i >= 1; i--) printf("%d", ans[i]);
printf("%d\n", ans[0]);
}
return 0;
}
本文介绍了一种求解多个整数最小公倍数的有效算法,适用于整数范围较大且数量较多的情况。通过质因数分解,记录每个质因数的最大次数,并以此为基础计算最小公倍数。
151

被折叠的 条评论
为什么被折叠?



