[noip2012]国王游戏<贪心+高精度>

题目链接:

https://vijos.org/p/1779

https://www.luogu.org/problem/show?pid=1080

http://codevs.cn/problem/1198/

 

终于过了。。。。。这道高精度总算是过了,为了这道题我还特意去学了高精度除以搞精度(虽然最后只需要高精度除以低精度)

这道题都是看新番国王游戏的时候突发奇想跑来做的QAQ。。。。

 

这道题的贪心思路是,按照左右手相乘来从小到大排序,乘积相同就按照右手从小到大。。。

至于为什么这么贪心,我个人的想法是,将右手数大的尽量排后面(除数比较大),然后也要让左手大的靠后(被除数小),

具体的证明可以看看这个博客:http://www.cnblogs.com/OIerLYF/p/7306156.html

然后排了序就是高精度除法,然后和当前的ans来比较,接着高精度乘法。。。

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<queue>
  8 #include<stack>
  9 #define maxn 10005
 10 using namespace std;
 11 int n;
 12 struct node{
 13     int l,r,sum;
 14 }e[maxn];
 15 int comp(const void*a,const void*b){
 16     if((*(struct node*)a).sum==(*(struct node*)b).sum)
 17     return (*(struct node*)a).r>(*(struct node*)b).r?1:-1;
 18     return (*(struct node*)a).sum>(*(struct node*)b).sum?1:-1;
 19 }
 20 
 21 int ans[maxn],s[maxn],val[maxn];
 22 
 23 void div(int s[],int q,int val[])
 24 {
 25     int rest=0,tot=0,p[maxn];
 26     for(int i=1;i<=s[0];i++){
 27         p[i]=s[s[0]-i+1];
 28     }p[0]=s[0];
 29     rest=p[1];int i=2;
 30     while(rest<q&&i<=p[0]){
 31         rest=rest*10+p[i];
 32         i++;
 33     }
 34     if(rest<q){val[0]=1;val[1]=0;return ;}
 35     else{
 36         tot++;val[tot]=rest/q;
 37         while(i<=p[0]){
 38             rest=rest%q*10+p[i];
 39             i++;
 40             tot++;
 41             val[tot]=rest/q;
 42         }
 43     }
 44     val[0]=tot;
 45 }
 46 
 47 void change(){
 48     for(int i=0;i<=val[0];i++)
 49         ans[i]=val[i];
 50 }
 51 
 52 void compare(int val[],int ans[]){
 53     if(val[0]>ans[0]){
 54         change();
 55     }else{
 56         if(val[0]==ans[0]){
 57             for(int i=1;i<=val[0];i++){
 58                 if(val[i]>ans[i]){
 59                     change();
 60                     return;
 61                 }else return;
 62             }
 63         }
 64     }
 65 }
 66 
 67 void mul(int s[],int k){
 68     for(int i=1;i<=s[0];i++){s[i]*=k;}
 69     for(int i=1;i<=s[0];i++){
 70         if(s[i]>=10){
 71             s[i+1]+=s[i]/10;
 72             s[i]=s[i]%10;
 73         }
 74     }
 75     while(s[s[0]+1]){
 76         s[0]++;
 77         s[s[0]+1]+=s[s[0]]/10;
 78         s[s[0]]%=10;
 79     }
 80 }
 81 
 82 int main(){
 83     scanf("%d",&n);
 84     for(int i=0;i<=n;i++){
 85         scanf("%d%d",&e[i].l,&e[i].r);
 86         e[i].sum=e[i].l*e[i].r;
 87     }
 88     qsort(e+1,n,sizeof(e[1]),comp);
 89     int k=e[0].l,tot=0;
 90     while(k){tot++;s[tot]=k%10;k/=10;}
 91     s[0]=tot;
 92     for(int i=1;i<=n;i++){
 93         memset(val,0,sizeof(val));
 94         div(s,e[i].r,val);
 95         compare(val,ans);
 96         mul(s,e[i].l);
 97     }
 98     for(int i=1;i<=ans[0];i++)
 99         printf("%d",ans[i]);    
100 }
View Code

【总结】

回顾了一下历年的考题,发现高精度其实考的不是很多。。但是这还是挺重要的方法,可以去学学。。

这一份代码中的高精度除以低精度都是我从今年noip2017提高组初赛试题学到的。。另外我顺便还积累了高精度除以高精度,确实很有用。。

然后卡了我很久的错误点就是那个比较环节。。。。比较环节位数相同时,逐位比较,有一位小于等于ans就break,不然就替换。。我就是忘记了跳出,所以一直卡着剩下的40%数据过不了

 

posted @ 2017-10-18 17:22  Danzel♂  阅读(558)  评论(0编辑  收藏  举报