lightoj 1024 Eid

题意:

求n个数的最小公倍数,n<1000,每个数<10000.

思路:

大数操作,先求出每个素数在每个数中出现的最多次数,相称后就是答案。

一开始开了一个数组存每一位的数,超时了,看了一下别人的代码,他是数组中一个位置存四位,正好相称是不会爆int,缩短了数组长度,节省了访问时间。

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<iomanip>
#include<string.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
ll s,n,anst[1005],ans[10005],tans[10005],top1;
bool isprime[10005];
int cutprime[10005],top;
void prime()
{
    for(int i=2; i<10005; i++)
    {
        if(isprime[i]==0)
            cutprime[top++]=i;
        for(int j=i+i; j<10005; j+=i)
            isprime[j]=1;
    }
}
void solve(int sum)
{
    for(int i=0; i<1005; i++)
        anst[i]*=sum;
    for(int i=0; i<1004; i++)
    {
        anst[i+1]+=anst[i]/10000;
        anst[i]%=10000;
    }//存储四位
}
void putout()
{
    int i=1004;
    while(anst[i]==0)
        i--;
    printf("%lld",anst[i]);
    i--;
    for(; i>=0; i--)
        printf("%04lld",anst[i]);//补零
    printf("\n");
}
int main()
{
    int t;
    scanf("%d",&t);
    prime();
    while(t--)
    {
        memset(ans,0,sizeof(ans));
        memset(anst,0,sizeof(anst));
        anst[0]=1;
        scanf("%lld",&n);
        for(int i=1; i<=n; i++)
        {
            memset(tans,0,sizeof(tans));
            scanf("%lld",&s);
            for(int i=0; i<top; i++)
            {
                if(s==1)
                    break;
                while(s%cutprime[i]==0)
                {
                    s/=cutprime[i];
                    tans[cutprime[i]]++;
                }
                ans[cutprime[i]]=max(ans[cutprime[i]],tans[cutprime[i]]);
            }
        }
        for(int i=0; i<top; i++)
        {
            for(int j=ans[cutprime[i]]; j>0; j--)
                solve(cutprime[i]);
        }
        printf("Case %lld: ",++top1);
        putout();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41049928/article/details/83113136