题目链接: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。
代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 const int N=1e4+5; 7 bool prime[N]; 8 int cnt[N]; 9 int ans[N]; 10 11 void is_prime(void){ 12 for(int i=2;i<N;i++) 13 prime[i]=true; 14 for(int i=2;i*i<N;i++){ 15 if(prime[i]){ 16 for(int j=i*i;j<N;j+=i){ 17 prime[j]=false; 18 } 19 } 20 } 21 } 22 //万进制高精度乘法 23 void Mul(int a[],int num) 24 { 25 for(int i=0; i<1000; i++) 26 a[i] = a[i]*num; 27 for(int i=0; i<1000; i++) 28 { 29 a[i+1] += a[i]/10000; 30 a[i] = a[i]%10000; 31 } 32 } 33 34 void Puts(int a[]){ 35 int pos=1000; 36 while(pos>=0&&ans[pos]==0) 37 pos--; 38 printf("%d",ans[pos--]); 39 while(pos>=0) 40 printf("%04d",ans[pos--]); 41 printf(" "); 42 } 43 44 int main(){ 45 is_prime(); 46 int T; 47 scanf("%d",&T); 48 int cas=0; 49 while(T--){ 50 memset(cnt,0,sizeof(cnt)); 51 memset(ans,0,sizeof(ans)); 52 int n; 53 scanf("%d",&n); 54 while(n--){ 55 int x; 56 scanf("%d",&x); 57 int d=2,count=0; 58 //把数字进行素因子分解,用cnt[]记录每种素因子出现的最大次数 59 while(d<=x){ 60 if(x%d==0&&prime[d]){ 61 x/=d; 62 count++; 63 cnt[d]=max(count,cnt[d]); 64 } 65 else{ 66 d++; 67 count=0; 68 } 69 } 70 } 71 //用高精度乘法,把素因子按对应次数乘起来 72 ans[0]=1; 73 for(int i=1;i<N;i++){ 74 if(cnt[i]){ 75 int t=1; 76 while(cnt[i]--) 77 t*=i; 78 Mul(ans,t); 79 } 80 } 81 //输出 82 printf("Case %d: ",++cas); 83 Puts(ans); 84 } 85 }