NOIP 2012 国王游戏

洛谷 P1080 国王游戏

洛谷传送门

JDOJ 1780: [NOIP2012]国王游戏 D1 T2

JDOJ传送门

Description

恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人左手上数乘积除以他自己右手上的数, 然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获奖赏最多的大臣,所尽可能少。 注意,国王的位置始终在队伍最前面。

Input

第一行包含一个整数 n ,表示大臣的人数 。

第二行包含两个整数 a 和 b ,之间用一个空格隔开,分别表示国王左手和右上的整数。

接下来 n 行,每行包含两个整数 a 和 b ,之间用一个空格隔开,分别表示每大臣左手和右手上的整数。

Output

输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得金币数。

Sample Input

3 1 1 2 3 7 4 4 6

Sample Output

2

HINT

对于20%的数据,有1 <= n <= 10, 0 < a,b < 8;

对于40%的数据,有1 <= n <= 20, 0 < a,b < 8;

对于60%的数据,有1 <= n <= 100,保证答案不超过109;

对于100%的数据,有1 <= n <= 1000, 0 < a,b < 10000。

题解:

一道贪心的好题。

就是高精度比较卡人...

在大家都会高精度的写法的前提下(滑稽.jpg)贪心策略就是把左右手乘积较大的大臣放在前面。

代码:

#include<bits/stdc++.h>
using namespace std;

struct minister
{
    int l,r,m;
}c[1010];

int ans,len,f,maxlen;
int a[10000],b[10000],d[10000],maxx[10000];
char str[10000];

int cmp(minister a,minister b)
{
    if (a.m==b.m)
        return a.r<b.r;
    else
        return a.m<b.m;
}

void multiply(int a[],int b)
{
    memset(d,0,sizeof(d));
    for(int i=1;i<=len;i++)
        d[i]=a[i]*b;
    for(int i=1;i<=len;i++)
    {
        if (d[i]/10!=0)
        {
            d[i+1]+=d[i]/10;
            d[i]%=10;
        }
    }
    while (d[len+1]!=0)
        len++;
    while (d[len]/10!=0)
    {
        d[len+1]+=d[len]/10;
        d[len]%=10;
        len++;
    }
    for(int i=1;i<=len;i++)
        a[i]=d[i];
}

void divide(int a[],int b)
{
    memset(d,0,sizeof(d)); 
    int x=0;
    for(int i=1;i<=len;i++)
    {
        d[i]=(a[i]+x*10)/b;
        x=(a[i]+x*10)%b;
    }
    int pd=0;
    for (int i=1;i<=len;i++) if (d[i]){
        pd=1;break;
    }
    if (pd)
    {
        int i=1;
        for(;d[i]==0;i++);
        f=i;
        for (;i<=len;i++)
        {
            if (d[i]>maxx[i] && len-f+1==maxlen || len-f+1>maxlen)
            {
                for (int j=f;j<=len;j++) maxx[j]=d[j];
                maxlen=len-f+1;
                break;
            }
            if (maxlen>len-f+1 ||d[i]<maxx[i]) break;
        }
    }
}
int main()
{
    int n;
    cin>>n;
    for (int i=0;i<=n;i++)
    {
        cin>>c[i].l>>c[i].r;
        c[i].m=c[i].l * c[i].r;
    }
    sort(c+1,c+n+1,cmp);
    for(int i=0;c[0].l;i++){
        str[i]=c[0].l%10+'0';
        c[0].l/=10;
    }
    len=strlen(str);
    for (int i=1;i<=len;i++) a[i]=str[i-1]-'0';
    for (int i=1;i<=len;i++) b[i]=str[len-i]-'0';
    for (int i=1;i<=n;i++)
    {
        divide(b,c[i].r);
        multiply(a,c[i].l);
        for (int j=1;j<=len;j++) b[j] = a[len-j+1];
    }
    for (int i=f;i<=maxlen+f-1;i++) cout<<maxx[i];
    return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/11779170.html