• 【?】吉利数字 [数位dp]


    中国人喜欢数字6和8。特别地,一些人喜欢满足含有特定个数6和8的数。现在请求出,在区间[L,R]之间的第K大的含有X个6和Y个8的数。

    输入的第一行包括4个数字,L,R,X,Y。

    接下来的一行给出该组数据的询问数Q。

    接下来Q行中,每行有一个整数K。

    对于某个询问,输出一行,为对应的第K大的数。如果不存在这个数则输出“That's too bad!”

    我终于了却了今日的心事QAQ 自己硬刚好久 写递推的太难受了

    首先是转移的时候要注意判断一下

    在递推写数位dp的时候要注意在最后枚举和x数位相同的数的时候判断一下这个数本身合不合法 QAQ我总忘这个

    最后是注意开long long!!!

    /*
    10000000000000 50000000000000 0 1
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define rg register
    const int N=2000000000+5,pw=11,inf=0x3f3f3f3f,P=19650827;
    ll a,b,x,y;
    ll base[20],f[20][10][20][20];
    template <class t>void rd(t &x)
    {
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    void pre(){
        base[0]=1ll;
        for(int i=1;i<=19;++i) base[i]=base[i-1]*10ll;
        for(int i=0;i<=9;++i) f[1][i][i==6][i==8]=1;
        for(int i=2;i<=19;++i)
        for(int j=0;j<=9;++j)
        for(int k=0;k<=9;++k)
        for(int h6=(j==6);h6<=i;++h6)
        for(int h8=(j==8);h8<=i-h6;++h8)
        f[i][j][h6][h8]+=f[i-1][k][h6-(j==6)][h8-(j==8)];
    }
    
    ll solve(ll xx){
        ll p=0,num[20],sum=0;
    //    for(p=0;p<=13;++p) if(base[p]>x) break;
        while(xx) num[++p]=xx%10,xx/=10;
        for(int i=1;i<p;++i)
        for(int j=1;j<=9;++j)
        sum+=f[i][j][x][y];
        for(int i=1;i<num[p];++i)
        sum+=f[p][i][x][y];
        int c6=0,c8=0;
        for(int i=p-1;i>0;--i){
            c6+=(num[i+1]==6),c8+=(num[i+1]==8);
            if(c6>x||c8>y) break;
            for(int j=0;j<num[i];++j){
            if((c6==x&&j==6)||(c8==y&&j==8)) continue;
             sum+=f[i][j][x-c6][y-c8];
            }
        }
        return sum;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("nocows.out","w",stdout);
        rd(a),rd(b),rd(x),rd(y);
        pre();
        ll up,dw;dw=solve(a+1);
        up=solve(b+1);
        int q;rd(q);
        for(int i=1;i<=18;++i) printf("%lld ",f[i][1][0][1]);
        while(q--){
            ll k;rd(k);
            ll l=a,r=b,mid,ans=-1;
            if(k+dw>up) printf("That's too bad!
    ");
            else{
                  while(l<r){
                mid=(l+r)>>1;
                   ll nw=solve(mid+1);
                   if(nw<dw+k) l=mid+1;
                   else r=mid,ans=1;
                   }
            printf("%lld
    ",l);
            }
        }
        return 0;
    }
  • 相关阅读:
    HTML5新增标签
    json和jsonp(json是目的,jsonp是手段)
    xml和json的区别
    display:inline 和display:inline-block和display:block的区别
    前后端数据交互方法(2)
    前端后端是如何交互的
    前端工程师的价值
    angularjs简述
    spring学习
    Hibernate(JPA ) 查询返回只有一个字段,返回类型设置为List<object []>,取值报错
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11005991.html
Copyright © 2020-2023  润新知