[NOIP2012] 國王遊戲
【題目描述】
恰逢 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] 國王遊戲