【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 }