zoukankan      html  css  js  c++  java
  • [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%数据过不了

     

  • 相关阅读:
    C#后台解析XML字符串并获取节点值
    table动态添加tr
    时间段检索时间段
    什么是数据结构
    PERSONAL VALUES
    C#接口
    基于ArcEngine与C#的鹰眼地图实现
    ENVI/IDL与ArcGIS集成开发的三种途径
    中国地图投影(实现Lambert投影)
    Git 的下载
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7687800.html
Copyright © 2011-2022 走看看