首页 > 代码库 > [NOIP2012] 提高组 洛谷P1080 国王游戏

[NOIP2012] 提高组 洛谷P1080 国王游戏

 

题目描述

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

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

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

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

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

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

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

输入输出格式

输入格式:

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

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

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

和右手上的整数。

输出格式:

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

金币数。

输入输出样例

输入样例#1:
3 1 1 2 3 7 4 4 6 
输出样例#1:
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%的数据,保证答案不超过 109;

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

NOIP 2012 提高组 第一天 第二题

 

经过凭感觉瞎搞大堆复杂的证明和推导,以每个人左手右手的乘积为标准,从小到大排序,然后从左往右乘起来,求在哪个位置可以取得最大值即可。

需要用到高精度。

↑高精度简直恶心,调了好久好久才对。

  1 /*by SilverN*/  2 #include<iostream>  3 #include<algorithm>  4 #include<cstring>  5 #include<cstdio>  6 #include<cmath>  7 using namespace std;  8 int read(){  9     int x=0,f=1;char ch=getchar(); 10     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();} 11     while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();} 12     return x*f; 13 } 14 struct HN{ 15     int a[2400]; 16     int len; 17 }num,c,ans; 18 bool cmp(HN a,HN b){ 19     if(a.len<b.len)return 1; 20     for(int i=a.len;i;--i){ 21         if(a.a[i]<b.a[i])return 1; 22         if(a.a[i]>b.a[i])return 0; 23     } 24     return 0; 25 } 26 void N_mul(int x){ 27     HN t;t.len=num.len+10; 28     memset(t.a,0,sizeof t.a); 29     for(int i=1;i<=num.len;i++){ 30         t.a[i]+=num.a[i]*x; 31         t.a[i+1]=t.a[i]/10000; 32         t.a[i]%=10000; 33     } 34 //    num.len+=10; 35     while(t.a[t.len]==0 && t.len>1) t.len--; 36     num=t; 37     return; 38 } 39 void N_div(int x){ 40     memset(c.a,0,sizeof c.a); 41     int tmp=0; 42     c.len=0; 43     for(int i=num.len;i;i--){ 44         tmp=10000*tmp+num.a[i]; 45         if(tmp>=x){ 46             if(!c.len) c.len=i; 47             c.a[i]=tmp/x; 48             tmp%=x; 49         } 50     } 51     return; 52 } 53 void PRI(HN num){     54     printf("%d",num.a[num.len]); 55     for(int i=num.len-1;i>0;--i){ 56         printf("%d",num.a[i]/1000); 57         printf("%d",num.a[i]/100%10); 58         printf("%d",num.a[i]/10%10); 59         printf("%d",num.a[i]%10); 60     } 61     printf("\n"); 62     return; 63 } 64 // 65 struct node{ 66     int a,b; 67     int c; 68 }m[1200]; 69 void qsort(int l,int r){ 70     if(l<r){ 71         int i=l,j=r; node x=m[l]; 72         while(i<j){ 73             while(i<j && m[j].c>=x.c) j--; 74             m[i]=m[j]; 75             while(i<j && m[i].c<=x.c) i++; 76             m[j]=m[i]; 77         } 78         m[i]=x; 79         qsort(l,i-1); 80         qsort(i+1,r); 81     } 82     return; 83 } 84 int n; 85 int main(){ 86     n=read(); 87     scanf("%d",&num.a[1]); 88     scanf("%d",&num.len); 89     num.len=1; 90     int i,j; 91     for(i=1;i<=n;i++){ 92         m[i].a=read(); 93         m[i].b=read(); 94         m[i].c=m[i].a*m[i].b; 95     } 96     qsort(1,n); 97 //    for(i=1;i<=n;i++)printf("%d ",m[i].c);printf("\n"); 98 //    for(i=1;i<=n;i++)printf("re:%d %d\n",m[i].a,m[i].b); 99     ans.len=1;100     ans.a[1]=0;101     for(i=1;i<=n;i++){102         N_div(m[i].b);103 //        PRI(c);104         if(cmp(ans,c))ans=c;105 //        PRI(ans);106 //        printf("num:");PRI(num); 107         N_mul(m[i].a);108     }109     PRI(ans);110     return 0;111 }

 

[NOIP2012] 提高组 洛谷P1080 国王游戏