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

Posted 西瓜不懂柠檬的酸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 10001
using 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个数的最小公约数+高精度)的主要内容,如果未能解决你的问题,请参考以下文章

lightoj-1024Eid (高精度)

LightOJ - 1117 Helping Cicada (求1~n有多少个数不能被这m个数中任意一个整除)(容斥+状态压缩)

A New Function LightOJ - 1098()

LightOJ 1336Sigma Function

Lightoj 1281 New Traffic System (记忆化Dijkstra)

Max Sum Plus Plus---hdu1024(动态规划求M段的最大和)