码迷,mamicode.com
首页 > 其他好文 > 详细

[NOIP2012] 国王游戏

时间:2017-05-14 13:56:37      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:void   span   max   define   log   存在   math   pre   str   

【题目描述】

恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

【输入格式】

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

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

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

【输出格式】

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

【样例输入】

3
1 1
2 3
7 4
4 6

【样例输出】

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。

【数据范围】

对于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 < 10^5。

思路{

  比较好的贪心。

  我的SB贪心不加高精竟然把除高精的分全拿了。。。。。真是醉了。调了我一上午,以为高精萎了,结果发现我的贪心错了。。。。

  考虑两个点的情况,,设存在 相邻大臣A(l1,r1),B(l2,r2),A,B前左手乘积为Sum :

    当A在B前时:则Ans=max(Sum/r1,Sum*l1/r2);

    当B在A前时: 则Ans=max(Sum/r2,Sum*l2/r1);

    显然 Sum*l2/r1>Sum/r1;Sum*l1/r2>Sum/r2,故只需比较Sum*l1/r2,Sum*l2/r1(打起来好麻烦啊。。。。。PS(fat cheng:麻烦了))

  Sum*l1/r2为①,Sum*l2/r1为②,Sum/r1为③,Sum/r2为④

    若①>②{l1*r1>l2*l2,有①>④,①>②>③。①为max,提前。}

    若②>①{r2*l2>l1*r1,有②>③,②>①>④。②为max,提前。}

  故只需按照li*ri从小到大排序,模拟+高精即可。

}

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #define RG register
 8 #define LL long long
 9 #define dd double
10 #define maxx 10003
11 using namespace std;
12 struct matrix{
13   int L,R;
14   matrix() {}
15   matrix(int l,int r):L(l),R(r) {}
16 }a[maxx];int n,ans[maxx],sum[maxx],chu[maxx],aa[maxx];
17 bool comp(const matrix & a,const matrix & b){return a.L*a.R<b.L*b.R;}
18 void chuyi(int num){int x=0;
19   int chu1[maxx];
20   memset(chu1,0,sizeof(chu1));
21   memset(chu,0,sizeof(chu));
22   for(int i=1;i<=sum[0];++i){
23     chu1[i]=(x*10+sum[i])/num;
24     x=(x*10+sum[i])%num;
25   }chu1[0]++;
26   while(!chu1[chu1[0]]&&chu1[0]<sum[0])chu1[0]++;
27   for(int i=chu1[0];i<=sum[0];++i)
28     chu[++chu[0]]=chu1[i];
29 }
30 void check(int num){
31   chuyi(num);
32   if(chu[0]<ans[0])return;
33   else if(chu[0]>ans[0]){
34     ans[0]=chu[0];
35     for(int i=1;i<=chu[0];++i)ans[i]=chu[i];
36   }
37   else {
38     for(int i=1;i<=ans[0];++i)if(ans[i]!=chu[i]){
39     if(ans[i]>chu[i])return;
40     else{
41       for(int j=1;j<=chu[0];++j)ans[j]=chu[j];
42       return;
43     }
44     }
45   }
46 }
47 void cheng(int num){
48   int c[maxx],d[maxx];
49   memset(c,0,sizeof(c));
50   memset(aa,0,sizeof(aa));
51   memset(d,0,sizeof(d));
52   while(num)c[++c[0]]=num%10,num/=10;
53   d[0]=sum[0];for(int i=1;i<=sum[0];++i)d[sum[0]-i+1]=sum[i];
54   for(int i=1;i<=d[0];++i){
55     int x=0;
56     for(int j=1;j<=c[0];++j){
57       aa[i+j-1]+=c[j]*d[i]+x;
58       x=aa[i+j-1]/10;aa[i+j-1]%=10;
59     }
60     aa[i+c[0]]=x;
61   }aa[0]=d[0]+c[0];
62   while(!aa[aa[0]]&&aa[0]>1)aa[0]--;
63   sum[0]=aa[0];for(int i=1;i<=sum[0];++i)sum[sum[0]-i+1]=aa[i];
64 }
65 int main(){
66   freopen("kinggame.in","r",stdin);
67   freopen("kinggame.out","w",stdout);
68   int x,y;scanf("%d%d%d",&n,&x,&y),a[0]=matrix(x,y);
69   for(int i=1;i<=n;++i)scanf("%d%d",&x,&y),a[i]=matrix(x,y);
70   sort(a+1,a+n+1,comp);
71   while(a[0].L){
72     aa[++aa[0]]=a[0].L%10;
73     a[0].L/=10;
74   }sum[0]=aa[0];
75   for(int i=1;i<=sum[0];++i)
76     sum[sum[0]-i+1]=aa[i];
77   for(int i=1;i<=n;++i)
78     check(a[i].R),cheng(a[i].L);
79   for(int i=1;i<=ans[0];++i)cout<<ans[i];
80   return 0;
81 }

 

[NOIP2012] 国王游戏

标签:void   span   max   define   log   存在   math   pre   str   

原文地址:http://www.cnblogs.com/zzmmm/p/6852076.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!