题目链接:https://vjudge.net/contest/28079#problem/T

题目大意:给你n个数求这些数的最小公倍数(约数)。

解题思路:还太菜了,看了别人的题解才会写,转自这里,每个数的大小是1~10000,且有2~1000个数,可能达到1000个4位数相乘,所以结果很大,将近4000位。所以要使用高精度计算,而且不能直接按照我们平时计算最小公倍数的算法(循环过来),因为数字太大,所以要改变思路,我们可以把一个数进行素因数分解,然后找到所有分解出来的素数对应的最大次数,然后再按每个出现的素数及其次数把结果乘起来即可。

例如样例

4

5 6 30 60

5 : 5 //说明最小公倍数的因子中一定有一个5

6 : 2*3 //说明最小公倍数的因子中一定有一个2和一个3;

30 : 2*3*5 //说明最小公倍数的因子中一定有一个2和一个3和一个5;

60 : 2^2*3*5 //说明最小公倍数的因子中一定有2个2和一个3和一个5;

所以我们可以忽略那些个数比较少的, 找到说明结果中一定含有 2个2 1个3 1个5,然后相乘得到答案60。

代码:

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e4+;
bool prime[N];
int cnt[N];
int ans[N]; void is_prime(void){
for(int i=;i<N;i++)
prime[i]=true;
for(int i=;i*i<N;i++){
if(prime[i]){
for(int j=i*i;j<N;j+=i){
prime[j]=false;
}
}
}
}
//万进制高精度乘法
void Mul(int a[],int num)
{
for(int i=; i<; i++)
a[i] = a[i]*num;
for(int i=; i<; i++)
{
a[i+] += a[i]/;
a[i] = a[i]%;
}
} void Puts(int a[]){
int pos=;
while(pos>=&&ans[pos]==)
pos--;
printf("%d",ans[pos--]);
while(pos>=)
printf("%04d",ans[pos--]);
printf("\n");
} int main(){
is_prime();
int T;
scanf("%d",&T);
int cas=;
while(T--){
memset(cnt,,sizeof(cnt));
memset(ans,,sizeof(ans));
int n;
scanf("%d",&n);
while(n--){
int x;
scanf("%d",&x);
int d=,count=;
//把数字进行素因子分解,用cnt[]记录每种素因子出现的最大次数
while(d<=x){
if(x%d==&&prime[d]){
x/=d;
count++;
cnt[d]=max(count,cnt[d]);
}
else{
d++;
count=;
}
}
}
//用高精度乘法,把素因子按对应次数乘起来
ans[]=;
for(int i=;i<N;i++){
if(cnt[i]){
int t=;
while(cnt[i]--)
t*=i;
Mul(ans,t);
}
}
//输出
printf("Case %d: ",++cas);
Puts(ans);
}
}
05-11 20:17