zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    最小生成树(Prim和Kruscal)
    SPFA(还是稍微写写吧,虽然没什么用)
    最短路径(随便写写)(Floyd,Bellman-Ford,Dijkstra)
    Just a Hook HDU
    数论逆元
    最长上升子序列(LIS)算法(附Codeforces Round #641 (Div. 2),B题题解)
    Educational Codeforces Round 86 (Rated for Div. 2)
    Codeforces Round #633 (Div. 2)
    Codeforces Round #631 (Div. 2)
    Mayor's posters(线段树离散化)
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11779170.html
Copyright © 2011-2022 走看看