jzoj(高中)3100. 【NOIP2012提高组】国王游戏

题目链接

题解:将Ai*Bi得出Ci,然后把Ci从小到大排一遍(A和B数组一起跟着C数组动),得出最佳队列,接着枚举每个大臣的金币数即可(要用高精度乘低精度和高精度除低精度)

#include
#include
#include
#include
using namespace std;
long long int n,a[1001],b[1001],c[1001],maxn[5001],an[5001],nm,na,v[5001],nv;
void px(long long int l,long long int r)
{
    long long int x=l,y=r,mid=c[(l+r)/2];
    while(x<=y)
    {
        while(c[x]mid)y--;
        if(x<=y)
        {
            long long int t=a[x];
            a[x]=a[y];
            a[y]=t;
            t=b[x];
            b[x]=b[y];
            b[y]=t;
            t=c[x];
            c[x]=c[y];
            c[y]=t;
            x++;y--;
        }
    }
    if(x9)
        {
            an[i+1]+=an[i]/10;
            an[i]%=10;
            if(i+1>na)
            {
                na++;
            }
        }
    }
    while(an[na]==0&&na>1)na--;
}
void pd()
{
    if(nm>nv)
    {
        return ;
    }
    if(nm==nv)
    {
        for(long long int i=nv;i>=1;i--)
        {
            if(maxn[i]>v[i])
            {
                return ;
            }
            else if(v[i]>maxn[i])
            {
                break;
            }
        }
    }
    memset(maxn,0,sizeof(maxn));
    for(long long int i=1;i<=nv;i++)
    {
        maxn[i]=v[i];
    }
    nm=nv;
}
void chu(long long int x)
{
    memset(v,0,sizeof(v));nv=0;
    long long int sd=0;
    for(long long int i=na;i>=1;i--)
    {
        sd=sd*10+an[i];
        if(sd>=b[x])
        {
            nv=max(nv,i);
            v[i]=sd/b[x];
            sd-=b[x]*v[i];
        }
    }
    pd();
}
int main()
{
//  freopen("game.in","r",stdin);
//  freopen("game.out","w",stdout);
    scanf("%lld",&n);
    for(int i=0;i<=n;i++)
    {
        scanf("%lld %lld",&a[i],&b[i]);c[i]=a[i]*b[i];
    }
    px(1,n);
    an[1]=1;na=1;cheng(0);
    for(int i=1;i<=n;i++)
    {
        chu(i);
        cheng(i);
    }
    for(long long int i=nm;i>=1;i--)
    {
        printf("%lld",maxn[i]);
    }
    return 0;
}

你可能感兴趣的:(jzoj(高中)3100. 【NOIP2012提高组】国王游戏)