• (数位dp)吉利数字 区间k大


    【题目描述】

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

    【输入】

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

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

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

    【输出】

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

    【输入样例】

     1 1000 1 1

    10

    1

    2

    3

    4

    5

    6

    7

    8

    9

    100

    【输出样例】

           68

    86

    168

    186

    268

    286

    368

    386

    468

    That's too bad!

    【数据范围】

      对于30%的数据,1<=L<=R<=100000

      对于100%的数据,1<=L<=R<=10^18

    对于100%的数据,1<=X,Y<=18, 1<=Q<=30

    暴力老鸽二分查找153ms

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e5+5;
      4 int tot,e[30];
      5 long long l,r,x,y,q,k;
      6 long long c[30][30][30];
      7 long long n,m;
      8 template<class t>void red(t &x)
      9 {
     10     int w=1;
     11     x=0;
     12     char ch=getchar();
     13     while(ch>'9'||ch<'0')
     14     {
     15         if(ch=='-')
     16             w=-1;
     17         ch=getchar(); 
     18     }
     19     while(ch>='0'&&ch<='9')
     20     {
     21         x=(x<<3)+(x<<1)+ch-'0';
     22         ch=getchar();
     23     } 
     24     x*=w;
     25 } 
     26 void input()
     27 {
     28     freopen("input.txt","r",stdin);
     29 }
     30 void dv(long long z)
     31 {
     32     tot=0;
     33     while(z)
     34     {
     35         e[++tot]=z%10;
     36         z/=10;
     37     } 
     38     e[tot+1]=0;
     39 }
     40 long long dfs(int pos,bool limit,long long num6,long long num8)
     41 {
     42     if(num6>x||num8>y)
     43         return 0;
     44     if(pos==0)
     45     {
     46         if(num6==x&&num8==y)
     47             return 1;
     48         return 0;
     49     }
     50     if(!limit&&~c[pos][num6][num8])
     51         return c[pos][num6][num8];
     52     int up=limit?e[pos]:9;
     53     long long ans=0;
     54     for(int i=0;i<=up;++i)
     55         ans+=dfs(pos-1,limit&&(i==up),num6+(i==6),num8+(i==8));
     56     if(!limit)
     57         c[pos][num6][num8]=ans;
     58     return ans;
     59 }
     60 long long gettot(long long z)
     61 {
     62     if(!z)
     63         return 0;
     64     dv(z);
     65     memset(c,-1,sizeof(c));
     66     return dfs(tot,1,0,0);
     67 }
     68 bool check(long long ll,long long j,long long z,long long &w)
     69 {
     70     w=gettot(j)-gettot(ll-1);
     71     return w<z;
     72 }
     73 long long getnum(long long z)
     74 {
     75     long long ll=l;
     76     long long rr=r;
     77     long long j,w=z;
     78     while(ll<=rr)
     79     {
     80         j=(ll+rr)>>1;
     81         if(check(ll,j,z,w))
     82         {
     83             ll=j+1;
     84             z-=w;
     85         }
     86         else
     87             rr=j-1;
     88     }
     89     return ll;
     90 }
     91 int main()
     92 {
     93     input();
     94     red(l);
     95     red(r);
     96     red(x);
     97     red(y);
     98     red(q);
     99     n=gettot(l-1);
    100     m=gettot(r);
    101     while(q--)
    102     {
    103         red(k);
    104         if(n+k>m)
    105             printf("That's too bad!
    ");
    106         else
    107             printf("%lld
    ",getnum(k));
    108     } 
    109     return 0;
    110 }
    dfs
  • 相关阅读:
    TableEx 控件 v1.0 [原创][免费][开源]
    js刷新页面
    SimpleAjax 开发包 v3.1 (简单的Ajax)
    oracle中的''空字符串和null居然是等价的
    HTTP 错误大全
    Ext2.0 form使用实例
    isqlweb (Web版 SQL Server 管理器)
    关于软件版本
    我的第一个C++程序——方块游戏 v1.0
    轻松实现UltraWebGrid中的分页控制
  • 原文地址:https://www.cnblogs.com/Achensy/p/11007766.html
Copyright © 2020-2023  润新知