zoukankan      html  css  js  c++  java
  • [hdu3943]K-th Nya Number

      挺正常的一道模板题。

      f[i][j][k]表示i位的数,有j个4,k个7的方案数。

      具体实现的话...我写了发二分答案。。需要注意的是二分时应该是mid=L+(R-L)/2。。不然分分钟爆longlong(unsigned long long党自行退散

      其实也可以从左端点开始慢慢爬。。。但总觉得比较蛋疼所以没敢写

      由网上题解可得,其实还可以确定答案的位数后,从高位往低位一个一个试= =...复杂度会比二分答案的少个log

      需要注意一下对0的特判。。

      对于从左端点爬到根再爬到右端点的奇怪姿势一直不敢碰。。药丸的节奏啊= =。。GDOI应该不会出这么sxbk的东西吧(手动立flag?

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ll long long
     6 using namespace std;
     7 struct poi{
     8     ll k;int id;
     9 }q[233];ll ans[233];
    10 ll f[20][21][21],ten[20];bool u[20][21][21];
    11 int i,j,x,y,X,Y,num;
    12 ll l,r,tmp;
    13 int s[23],len;
    14 
    15 bool cmp(poi a,poi b){return a.k<b.k;}
    16 inline ll get(ll x){
    17     for(tmp=x,len=0;tmp;tmp/=10)s[++len]=tmp%10;
    18     if(!x)s[len=1]=0;
    19     ll ans=0;register int i,j;int sx=X,sy=Y;
    20     if(X+Y>len)return 0;
    21     for(i=sx+sy;i<len;i++)
    22         for(j=1;j<=9;j++)
    23             if((sx||j!=4)&&(sy||j!=7))ans+=f[i-1][sx-(j==4)][sy-(j==7)];
    24 //    printf("     %lld
    ",ans);
    25     for(i=1;i<s[len];i++)
    26         if((sx||i!=4)&&(sy||i!=7))ans+=f[len-1][sx-(i==4)][sy-(i==7)];
    27     sx-=s[len]==4,sy-=s[len]==7;
    28     for(i=len-1;i&&sx>=0&&sy>=0;i--){
    29         for(j=0;j<s[i];j++)
    30             if((sx||j!=4)&&(sy||j!=7))ans+=f[i-1][sx-(j==4)][sy-(j==7)];
    31         sx-=s[i]==4,sy-=s[i]==7;
    32     }
    33     if(!sx&&!sy&&x)ans++;
    34 //    printf("     %lld
    ",ans);
    35     return ans+(!X&&!Y);
    36 }
    37 int main(){
    38     f[1][1][0]=f[1][0][1]=1;f[1][0][0]=8;f[0][0][0]=1;
    39     for(i=ten[0]=1;i<=18;i++)ten[i]=ten[i-1]*10;
    40     for(i=2;i<=19;i++){
    41         for(x=1;x<=i;x++)for(y=i-x;y;y--)
    42             f[i][x][y]=x<=y?(f[i-1][x][y]*8+f[i-1][x-1][y]+f[i-1][x][y-1]):f[i][y][x]
    43         ;//    ,printf("  %d %d %d   %lld
    ",i,x,y,f[i][x][y]);
    44         for(x=1;x<=i;x++)f[i][x][0]=f[i][0][x]=f[i-1][x-1][0]+f[i-1][x][0]*8;
    45         f[i][0][0]=f[i-1][0][0]<<3;
    46     //    if(i<=3)
    47     //    for(x=0;x<=i;x++)for(y=0;y<=i-x;y++)printf("  %d %d %d  %lld
    ",i,x,y,f[i][x][y]);
    48     }
    49     int T,TT;scanf("%d",&TT);
    50     for(T=1;T<=TT;T++){
    51         scanf("%lld%lld%d%d",&l,&r,&X,&Y);scanf("%d",&num);
    52         for(i=1;i<=num;i++)scanf("%lld",&q[i].k),q[i].id=i;
    53         
    54         sort(q+1,q+1+num,cmp);
    55         ans[0]=l;
    56         ll lnum=get(l),mx=get(r)-lnum;
    57         
    58     //    printf("    lnum:%lld   mx:%lld
    ",lnum,mx);
    59         printf("Case #%d:
    ",T);
    60         for(i=1;i<=num;i++){
    61             ll L=ans[q[i-1].id],R=r,mid;
    62             if(q[i].k==q[i-1].k){ans[q[i].id]=L;continue;}
    63             if(q[i].k>mx){ans[q[i].id]=-1;continue;}
    64             while(L<R){
    65                 mid=L+((R-L)>>1);//printf("   %lld %lld  
    ",L,R);
    66                 if(get(mid)>=q[i].k+lnum)R=mid;else L=mid+1;
    67             }//puts("");
    68             ans[q[i].id]=L;
    69         }
    70         for(i=1;i<=num;i++)
    71             if(ans[i]==-1)puts("Nya!");else printf("%lld
    ",ans[i]);
    72     }
    73     return 0;
    74 }
    View Code

      话说网上有些题解遇到极限数据会炸>_<。。

  • 相关阅读:
    Mozilla Prism v0.9 For Windows/Linux/Mac
    Firefox 3.0十大年夜新特征(1)
    刊行版:Epidemic GNU/Linux 2.1发布
    斥地版:Red Hat Enterprise Linux 4.7 Beta公布公布
    linux下安装drcom1.3.7心得
    Oracle老手艺对Linux意味着什么?
    学Linux要火山式的驾御还是垂垂来
    Firefox 3.0 RC2本周颁发
    net命令详解 **net accounts /maxpwage:unlimited
    学习官方示例 TApplication.OnDeactivate
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5223916.html
Copyright © 2011-2022 走看看