首页 > 代码库 > LightOj1024 - Eid (求n个数的最小公约数+高精度)

LightOj1024 - Eid (求n个数的最小公约数+高精度)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1024

题意:给你n(2<=n<=1000)个数, 然后求n个数的最小公倍数,每个数的大小是1---10000;所以答案会很大,可能达到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;

需要注意的是,因为每次进行大整数相乘时都是用的N,以至于TLE了无数次,所以可以用多位一起输出的方法进行;

 

技术分享
#include <stdio.h>#include <string.h>#include <algorithm>#include <math.h>typedef long long LL;#define N 10001using namespace std;const double eps = 1e-6;int f[101], p[101], k = 0;void Prime(){    for(int i=2; i<101; i++)    {        if(!f[i])p[k++] = i;        for(int j=i; j<101; j+=i)            f[j] = 1;    }}int ans[1001], cnt[N];void Mul(int a[], int num){    for(int i=0; i<1000; i++)        a[i] = a[i]*num;    for(int i=0; i<1000; i++)    {        a[i+1] += a[i]/10000;        a[i] = a[i]%10000;    }}void PUTS(int a[]){    int i=1000;    while(i>=0 && a[i]==0) i--;    printf("%d", a[i--]);    while(i>=0) printf("%04d", a[i--]);    printf("\n");}int main(){    Prime();    int n, T, t = 1;    scanf("%d", &T);    while(T--)    {        memset(cnt, 0, sizeof(cnt));        memset(ans, 0, sizeof(ans));        int num;        scanf("%d", &n);        for(int i=1; i<=n; i++)        {            scanf("%d", &num);            for(int j=0; j<k && p[j]*p[j] <= num; j++)            {                int s = 0;                while(num%p[j] == 0)                {                    s ++;                    num /= p[j];                }                cnt[p[j]] = max(cnt[p[j]], s);            }            if(num > 1)                cnt[num] = max(cnt[num], 1);        }        ans[0] = 1;        for(int i=0; i<N; i++)        {            if(!cnt[i]) continue;            int ret = 1;            for(int j=0; j<cnt[i]; j++)                ret *= i;            Mul(ans, ret);        }        printf("Case %d: ", t++);        PUTS(ans);    }    return 0;}
View Code

 

LightOj1024 - Eid (求n个数的最小公约数+高精度)