• 【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
  • 相关阅读:
    如何有效的写算法题的几个小tips
    题目
    记录加入博客园,申请开通cnblog
    关于套接字socket程序参数设置
    int main (int argc, const char * argv[0])及指针数组与数组指针
    sleep函数
    signal函数
    C htonl()函数
    位域unsigned char a:4
    关于TCP和UDP的一个理解
  • 原文地址:https://www.cnblogs.com/JSL2018/p/5939885.html
Copyright © 2020-2023  润新知