JZOJ 3100. 国王游戏 (Standard IO) 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。

分析

                    题目分析:

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

                    队列可能是这样的:

* Left Right
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)

                    队列也有可能是这样的

* Left Right
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 }

猜你喜欢

转载自www.cnblogs.com/zjzjzj/p/10293297.html