首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【NOIP2012】国王游戏

这一次高精度完美地过辣好开心OvO,还get到了非常方便的高精度除小于10000的方法,这个是我自己脑出来的OvO

看来下午高精度傻逼得值qvq

原题:

恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右 手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排 成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

1 ≤ n ≤1,000,0 < a、b < 10000。

 

最大的最小,看上去好像二分的样子,然而没有单调性没法二分

可以先只看两个之间,只看这两个人的话前面的都不用管了,如果a1/b2>a2/b1,=>a1*b1>a2*b1,然后交换这两个就可以让这两个人中较大的更小

(网上题解是这么说的,我没看懂

然后按照a*b升序排序,模拟一下即可

数很大,要高精度

小技巧:

高精度除一个小于10000的数,直接用万进制从高位开始除,把除剩下的数也就是这一位膜除的数的结果乘10000加到下一位上去,继续往下除

结果的长度是被除数的长度-(被除数最高位>除数)

其它单精度数也可以这么玩儿,效率未知,应该不会太慢

好开心OvO

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 const int ss=10000;
 8 int read(){int z=0,mark=1;  char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
11     return z*mark;
12 }
13 int n;  struct cdd{int a,b;}a[1100];
14 bool compare(cdd x,cdd y){  return x.a*x.b<y.a*y.b;}
15 int mul_a[1100000],mul_b[1100000],ans[1100000];
16 int c[1100000];
17 void copy(int *x,int *y){memset(y,0,sizeof(y));  y[0]=x[0];  for(int i=1;i<=x[0];i++)  y[i]=x[i];}
18 void cheng(int *x,int z){
19     for(int i=1;i<=x[0];i++)  x[i]*=z;
20     for(int i=1;i<=x[0];i++)  x[i+1]+=x[i]/ss,x[i]%=ss;
21     while(x[x[0]+1]){  x[0]++;  x[x[0]+1]+=x[x[0]]/ss,x[x[0]]%=ss;}
22 }
23 bool bi(int *x,int *y){
24     if(x[0]>y[0])  return true;
25     if(x[0]<y[0])  return false;
26     for(int i=x[0];i>=1;i--)if(x[i]!=y[i])  return x[i]>y[i];
27     return true;
28 }
29 void chu(int *x,int *y,int z){//因为除的数<10000,刚好在万进制范围内,就直接除单精了
30     copy(y,c);
31     x[0]=c[0]-(c[c[0]]<z);
32     for(int i=c[0];i>=1;i--){
33         x[i]=c[i]/z;
34         c[i-1]+=(c[i]%z)*ss;
35     }
36     for(int i=1;i<=x[0];i++)  x[i+1]+=x[i]/ss,x[i]%=ss;
37     while(x[x[0]+1]){  x[0]++;  x[x[0]+1]+=x[x[0]]/ss,x[x[0]]%=ss;}
38 }
39 int main(){//freopen("ddd.in","r",stdin);
40     cin>>n;
41     for(int i=0;i<=n;i++)  a[i].a=read(),a[i].b=read();
42     sort(a+1,a+n+1,compare);
43     mul_a[mul_a[0]=1]=a[0].a;
44     for(int i=1;i<=n;i++){
45         chu(mul_b,mul_a,a[i].b);
46         if(bi(mul_b,ans))  copy(mul_b,ans);
47         cheng(mul_a,a[i].a);
48     }
49     cout<<ans[ans[0]];
50     for(int i=ans[0]-1;i>=1;i--)  printf("%04d",ans[i]);
51     cout<<endl;
52     return 0;
53 }
View Code

 

posted on 2016-10-08 19:22  cdcq_old  阅读(254)  评论(0编辑  收藏  举报