zoukankan      html  css  js  c++  java
  • ZOJ-3962-数位dp

     
     
     
     
     
     
        16进制下的数位dp,由于固定了位数,可以出现前导零,反而简化了问题,和十进制异曲同工,只需要注意边界,对于[l,r],如果r>max,则分成[l,max-1]+max+[0,r-max-1],这是因为对于cal(N,x)函数来说计算的是[0,N)之间x的出现次数,并不包括N,如果只是简单的把max+1传进去的话就不是八位数了,这
    样乱改函数的话更麻烦还不如直接把max抽出来计算方便。
        
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long 
     4 LL c[20]={6,2,5,5,4,5,6,3,
     5           7,6,6,5,4,5,5,4};
     6 LL f[20]={0,1};
     7 LL p16[20]={1};
     8 LL bit[20];
     9 void init(){
    10     for(LL i=1;i<=10;++i) p16[i]=p16[i-1]*16;
    11     for(LL i=2;i<=10;++i) f[i]=f[i-1]*16+p16[i-1];
    12 }
    13 LL cal(LL N,LL x){
    14     LL len=0,ans=0,tot=0;
    15     while(N){
    16         bit[len++]=N%16;
    17         N/=16;
    18     }
    19     while(len<8) bit[len++]=0;
    20     bit[len]=-1;
    21     for(LL i=len-1;i>=0;--i){
    22         ans+=f[i]*bit[i];
    23         if(bit[i]>x) ans+=p16[i];
    24         ans+=tot*bit[i]*p16[i];
    25         if(bit[i]==x) tot++;
    26     }
    27     return ans;
    28 }
    29 LL to10(char *s){
    30     LL ans=0,len=strlen(s);
    31     for(int i=0;i<len;++i){
    32         LL tmp=isdigit(s[i])?s[i]-'0':(s[i]-'A'+10);
    33         ans=ans*16+tmp;
    34     }
    35     return ans;
    36 }
    37 int main(){init();
    38     char s[15];
    39     LL l,r,t,n,i,j,k;
    40     LL MAX=to10("FFFFFFFF");
    41     scanf("%lld",&t);
    42     while(t--){
    43         scanf("%lld",&k);
    44         scanf("%s",s);
    45         LL l=to10(s);
    46         LL r=l+k-1;
    47         LL ans=0;
    48         
    49         if(r<=MAX){
    50             for(i=0;i<=15;++i) ans+=c[i]*(cal(r+1,i)-cal(l,i));
    51         }
    52         else{
    53             for(i=0;i<=15;++i) if(MAX>=l)ans+=c[i]*(cal(MAX,i)-cal(l,i));
    54             ans+=c[15]*8;
    55             for(i=0;i<=15;++i) ans+=c[i]*cal(r-MAX,i);
    56         }
    57         printf("%lld
    ",ans);
    58     }
    59     return 0;
    60 }
    61 /*
    62 10
    63 5 89ABCDEF
    64 3 FFFFFFFF
    65 7 00000000
    66 */
  • 相关阅读:
    SQLite out of order error备忘
    SQLITE_TOOBIG
    Android CursorWindow问题备忘
    SQLite3神奇的UNION、UNION ALL与LIMIT组合
    Android Database(SQLite)参数绑定问题初探
    Android SQLite 加入自定义函数
    修改替换/system/framework/framework.jar后重启手机为何没有效果?
    手动调用NDK编译HelloWorld
    第一篇
    程序题
  • 原文地址:https://www.cnblogs.com/zzqc/p/9009735.html
Copyright © 2011-2022 走看看