zoukankan      html  css  js  c++  java
  • JZOJ 3100. 国王游戏 NOIP2012

    题目

       

    Description

    恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右

    手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排

    成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每

    位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右

    手上的数,然后向下取整得到的结果。 

    国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,

    使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

     

    Input

    输入文件为game.in。 

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

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

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

    和右手上的整数。

    Output

    输出文件名为game.out。 

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

    金币数。

     

    Sample Input

    3 
    1 1 
    2 3 
    7 4 
    4 6

    Sample Output

    2 
    【输入输出样例说明】 
    按1、2、3号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为2; 
    按1、3、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2; 
    按2、1、3这样排列队伍,获得奖赏最多的大臣所获得金币数为2; 
    按2、3、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9; 
    按3、1、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2; 
    按3、2、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9。 
    因此,奖赏最多的大臣最少获得2个金币,答案输出2。
     

    Data Constraint

     
     

    Hint

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

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

    对于60%的数据,有1≤ n≤100; 

    对于60%的数据,保证答案不超过10^9; 

    对于100%的数据,有1 ≤ n ≤1,000,0 < a、b < 10000。

    分析

                        题目分析:

                        我们对于国王身后的两个点来分析

                        队列可能是这样的:

    *LeftRight
    king: a_0a0 b_0b0
    p1 a_1a1 b_1b1
    p2 a_2a2 b_2b2

                        那么我们计算可得ans_1ans1=max(frac{a_0}{b_1},frac{a_0*a_1}{b_2})max(b1a0,b2a0a1)

                        队列也有可能是这样的

    *LeftRight
    king: a_0a0 b_0b0
    p2 a_2a2 b_2b2
    p1 a_1a1 b_1b1

                        那么我们计算可得ans_2ans2=max(frac{a_0}{b_2},frac{a_0*a_2}{b_1})max(b2a0,b1a0a2)

                        我们来对比一下两个答案:

                        ans_1ans1=max(frac{a_0}{b_1},frac{a_0*a_1}{b_2})max(b1a0,b2a0a1)

                        ans_2ans2=max(frac{a_0}{b_2},frac{a_0*a_2}{b_1})max(b2a0,b1a0a2)

                        可以替换得:

                        ans_1ans1=max(k_1,k_2)max(k1,k2)

                        ans_2ans2=max(k_3,k_4)max(k3,k4)

                        显然我们可以得到:

                        frac{a_0*a_1}{b_2}b2a0a1>frac{a_0}{b_2}b2a0

                        frac{a_0*a_2}{b_1}b1a0a2>frac{a_0}{b_1}b1a0

                        即: k_2k2>k_3k3

                        k_4k4>k_1k1

                        如果ans_1ans1<ans_2ans2

                        那么易得:

                        k_4>k_2k4>k2

                        即: frac{a_0*a_2}{b_1}b1a0a2>frac{a_0*a_1}{b_2}b2a0a1

                        变形可得:

                        a_1*b_1<a_2*b_2a1b1<a2b2

                        当a_1*b_1<a_2*b_2a1b1<a2b2时,我们也能够得到ans_1ans1<ans_2ans2的结论

                        所以,为了ansans取到最小值,我们需要将a_i*b_iaibi较小的放在前面

                        那么我们以a_i*b_iaibi为关键字排序即可

                        同时,统计答案时一定不要忘了写高精度!

    代码

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 using namespace std;
      5 struct sb 
      6 {
      7     int l,r,cj;
      8 }a[1001];
      9 bool cmp(sb a,sb b)
     10 {
     11     return a.cj<b.cj?true:false;
     12 }
     13 string minn="0";
     14 int f[10001];
     15 string x1;
     16 void cf(int x)
     17 {
     18     for (int i=10000;i>=1;i--)
     19        f[i]*=x;
     20     for (int i=10000;i>=1;i--)
     21     {
     22         f[i-1]+=f[i]/10;
     23         f[i]%=10;
     24     }
     25     int j=1;
     26     while (f[j]==0)
     27        j++;
     28     x1="";
     29     for (int i=j;i<=10000;i++)
     30         x1+=f[i]+'0';
     31     
     32 }
     33 /*string div(string a,long long b)   //神奇的高精除
     34 {
     35     string r,ans;
     36     int d=0;
     37     if(a=="0") return a;
     38     for(int i=0;i<a.size();i++)
     39     {
     40             r+=(d*10+a[i]-'0')/b+'0';
     41             d=(d*10+(a[i]-'0'))%b;
     42     }
     43     int p=0;
     44     for(int i=0;i<r.size();i++)
     45     if(r[i]!='0')
     46      {
     47         p=i;
     48         break;
     49      }
     50     return r.substr(p);
     51 }*/
     52 int chu[10077],chu2[10077];
     53 string chuu(string a,int b)   //普通高精除
     54 {
     55     string ans;
     56     for (int i=0;i<a.size();i++)
     57        chu[i+1]=a[i]-'0';
     58     int c=0;
     59     for (int i=1;i<=a.size();i++)
     60     {
     61         chu[i]=chu[i]+(c*10);
     62         c=chu[i]%b;
     63         chu2[i]=chu[i]/b;
     64     }
     65     int j=1;
     66     while (chu2[j]==0) j++;
     67     for (int i=j;i<=a.size();i++)
     68       ans+=chu2[i]+'0';
     69     return ans;
     70 }
     71 int main ()
     72 {
     73     int n;
     74     cin>>n;
     75     int xx,y;
     76     cin>>xx>>y;
     77     for (int i=1;i<=n;i++)
     78     {
     79         cin>>a[i].l>>a[i].r;
     80         a[i].cj=a[i].l*a[i].r;
     81     }
     82     sort(a+1,a+1+n,cmp);
     83     f[10000]=1;
     84     cf(xx);
     85     for (int i=1;i<=n;i++)
     86     {
     87         string ans=chuu(x1,a[i].r);
     88         if (ans.size()!=minn.size())     //字符比较大小要先让位数一样
     89         {
     90             if (ans.size()>minn.size())
     91             {
     92                 string t;
     93                 for (int i=1;i<=ans.size()-minn.size();i++)
     94                    t+="0";
     95                 t+=minn;
     96                 minn=t;
     97                 t="";
     98             }
     99             else
    100             {
    101                 string t;
    102                 for (int i=1;i<=minn.size()-ans.size();i++)
    103                     t+="0";
    104                 t+=ans;
    105                 ans=t;
    106                 t="";
    107             }
    108             
    109         }
    110         if (ans>minn)
    111            minn=ans;
    112         cf(a[i].l);
    113     }
    114     cout<<minn;
    115 }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    【秒懂音视频开发】03_重识音频
    【秒懂音视频开发】02_重识声音
    【秒懂音视频开发】01_移动通信技术的发展
    [mysql]错误解决之"Failed to start MySQL Server"
    Ubuntu 将Python从默认的2.7升级到3.* 版本
    宝塔面板后台设置免费SSL证书Let's Encrypt(三)
    Let's Encrypt 证书申请及配置(二)
    快速签发 Let's Encrypt 证书指南(一)
    DJANGO中多种重定向方法使用
    反解法|逆向思维
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10293297.html
Copyright © 2011-2022 走看看