• 【noip2012】【luogu1080】国王的游戏[高精度][贪心]


    P1080 国王游戏

    推那个贪心直接自己推就好了,最后推出来最优解在a*b按从小到大排序中

    就在读入完后排序  再按排好的顺序一个一个比较出这个方案中得到最多钱的值 这个值就是答案

    推导:略   (真的不是我想咕咕咕

    最最最最最最最重要的是我打这题时的艰难改的过程

    因为对模版理解不彻底 导致自己背着打的时候全都是错误!!!!!

    我的一些错误或者是需要注意的地方

    • 压位之后的数组从左往右是从低位到高位排序的   eg:123456存进去是这样 [1234] [56]  所以比较是要从高位到低位逐一比较(理解了的应该都晓得QAQ)
    • 然后要用高精/低精 我开始懒得写高精/低精 然后就想的把那个低精转为高精去按高精/高精来搞,结果emmmmmmm过于慢了 因为高精/高精是挨个挨个减,然后那个除数太小了......
    • 然后是一些低级错误QAQ  j 打成 i 什么的

    代码里的加还有减都用不到 主要是我想背一下,然后写题解的时候懒得删了

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define rg register
      4 const int base=10000,power=4;
      5 const int N=10000+5;
      6 int n;
      7 template<class t>void rd(t &x)
      8 {
      9     x=0;int w=0;char ch=0;
     10     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
     11     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
     12     x=w?-x:x;
     13 }
     14 
     15 struct node{
     16     int a,b,c;
     17     bool operator <(const node x) const{return c<x.c;}
     18 }e[N];
     19 
     20 struct num{
     21     int a[N];
     22     num(){memset(a,0,sizeof(a));}
     23     num(int x)
     24     {//低精度转高精度
     25         memset(a,0,sizeof(a));
     26         int t=0;
     27         while(x)
     28         {
     29             a[++t]=x%base;
     30             x/=base;
     31         }
     32         a[0]=t;
     33     }
     34     void print()
     35     {
     36         printf("%d",a[a[0]]);
     37         for(rg int i=a[0]-1;i>0;--i)
     38         printf("%0*d",power,a[i]);//这句的意思就是 如果输出的长度不足power的话就用0来补位
     39 //例子:如果a[i]=12的话 而power=4 所以输出的是0012
     40         printf("
    ");
     41     }
     42 }p,pai,nw,ans;
     43 //p是当前大臣左手的数 nw是当前大臣所得的钱 pai是累乘的积 
     44 bool operator <(const num &p,const num &q)
     45 {
     46     if(p.a[0]<q.a[0]) return 1;
     47     if(p.a[0]>q.a[0]) return 0;
     48     for(rg int i=p.a[0];i>0;--i)//从高位到低位逐一比较
     49     if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i];
     50     return 0;
     51 }
     52 
     53 num operator +(const num &p,const num &q)//高精+
     54 {
     55     num c;
     56     c.a[0]=max(p.a[0],q.a[0]);
     57     for(rg int i=1;i<=c.a[0];++i)
     58     {
     59         c.a[i]+=p.a[i]+q.a[i];
     60         c.a[i+1]+=c.a[i]/base,c.a[i]%=base;
     61     }
     62     if(c.a[c.a[0]+1]) ++c.a[0];
     63     return c;
     64 }
     65 
     66 num operator -(const num &p,const num &q)//高精-
     67 {
     68     num c=p;
     69     for(rg int i=1;i<=q.a[0];++i)
     70     {
     71         c.a[i]-=q.a[i];
     72         if(c.a[i]<0) --c.a[i+1],c.a[i]+=base;
     73     }
     74     while(c.a[0]>0&&!c.a[c.a[0]]) --c.a[0];
     75     return c;
     76 }
     77 
     78 num operator *(const num &p,const num &q)//高精*
     79 {
     80     num c;
     81     c.a[0]=p.a[0]+q.a[0]-1;
     82     for(rg int i=1;i<=p.a[0];++i)
     83     for(rg int j=1;j<=q.a[0];++j)
     84     {
     85         c.a[i+j-1]+=p.a[i]*q.a[j];
     86         c.a[i+j]+=c.a[i+j-1]/base,c.a[i+j-1]%=base;
     87     }
     88     //while(c.a[0]>1&&!c.a[c.a[0]]) --c.a[0];
     89     while(c.a[c.a[0]+1]) ++c.a[0];
     90     return c;
     91 }
     92 
     93 num operator /(const num &p,const int &q)//高精/低精
     94 {
     95     num x;
     96     int y=0;
     97     for(rg int i=p.a[0];i>=1;--i)
     98     {
     99         y=y*base+p.a[i];
    100         if(y>=q) x.a[i]=y/q,y%=q;
    101     }
    102     x.a[0]=p.a[0];
    103     while(x.a[0]>=1&&!x.a[x.a[0]]) --x.a[0];//去前导0
    104     return x;
    105 }
    106 
    107 int main()
    108 {
    109     //freopen("testdata.in-3.txt","r",stdin);
    110     rd(n);int q;
    111     for(rg int i=0;i<=n;++i) rd(e[i].a),rd(e[i].b),e[i].c=e[i].a*e[i].b;
    112     sort(e+1,e+1+n);
    113     pai=num(e[0].a);
    114     for(rg int i=1;i<=n;++i)
    115     {
    116         p=num(e[i].a),q=e[i].b;
    117         nw=pai/q,pai=pai*p;
    118         if(ans<nw) ans=nw;
    119     }
    120     //pai.print();
    121     ans.print();
    122     return 0;
    123 }

    放一个高精/高精   (我开始打的时候把y.re()放进while里了QAQ)

     1 num operator / (const num &p, const num &q)
     2 {  
     3     num x, y;  
     4     for (int i = p.a[0];i >= 1;--i)                       //从最高位开始取数  
     5     {  
     6         y.add(p.a[i]);  //把数添到末尾(最低位),这时候是高位在前,低位在后  
     7         y.re();           //把数反过来,变为统一的存储方式:低位在前,高位在后  
     8         while ( !(y < q) )         //大于等于除数的时候,如果小于的话,其实答案上的该位就是初始的“0”  
     9             y = y - q, ++x.a[i];   //看能减几个除数,减几次,答案上该位就加几次。  
    10         y.re();                    //将数反过来,为下一次添数做准备  
    11     }  
    12     x.a[0] = p.a[0];
    13     while (x.a[0] > 0 && !x.a[x.a[0]]) --x.a[0];  
    14     return x;  
    15 }  

    在struct num里要加这两句

    void add(int k) {if(k||a[0]) a[++a[0]]=k;}
    void re() {reverse(a+1,a+1+a[0]);}
  • 相关阅读:
    【转】算法的时间复杂度
    FFT 物理意义(转)
    【转】FIR学习1
    【转】DFT DTFT DFS FFT的关系
    【转】TCL中的数组
    【转】setup time和hold time的周期问题(slack)
    【转】TCL语法简介
    【转】亚稳态分析
    ubuntu下Samba服务器搭建
    第一次生成uImage出现的问题解决
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/10740363.html
Copyright © 2020-2023  润新知