http://acm.hdu.edu.cn/showproblem.php?pid=3943

题目意思是说一个数字由X个4和Y个7和其他不包含4和7的数字组成,则这个数是

Nya数,求给定区间的第K个Nya数。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 #define N 25
 6 #define ll __int64
 7 ll dp[N][N][N],p,q,x,y;
 8 void init()
 9 {
10     memset(dp,0,sizeof(dp));
11     dp[0][0][0]=1;
12     dp[1][0][0]=8;
13     dp[1][1][0]=1;
14     dp[1][0][1]=1;
15     for(int i=2;i<20;i++)
16     //for(int j=0;j<10;j++)
17     for(int i1=0;i1<21;i1++)
18     for(int j1=0;j1<21;j1++){
19         if(i1>0)
20         dp[i][i1][j1]+=dp[i-1][i1-1][j1];
21         if(j1>0)
22         dp[i][i1][j1]+=dp[i-1][i1][j1-1];
23         dp[i][i1][j1]+=8*dp[i-1][i1][j1];
24     }
25 }
26 ll solve(ll x1)
27 {
28     ll dig[20],cnt=0,flag=0,ans=0,xx=x,yy=y;
29     while(x1){
30         dig[++cnt]=x1%10;
31         x1/=10;
32     }
33     for(int i=cnt;i>0&&!flag;i--){
34         for(int j=0;j<dig[i];j++){
35             if(j==4&&xx>0)
36             ans+=dp[i-1][xx-1][yy];
37             else if(j==7&&yy>0)
38             ans+=dp[i-1][xx][yy-1];
39             else if(j!=4&&j!=7)
40             ans+=dp[i-1][xx][yy];
41         }
42         if(dig[i]==4)
43             xx--;
44         if(dig[i]==7)
45             yy--;    
46         if(xx<0||yy<0)
47             flag=1;
48     }
49     return ans;
50 }
51 int main()
52 {
53     init();
54     int t,cas=1;
55     scanf("%d",&t);
56     while(t--){
57         scanf("%I64d%I64d%I64d%I64d",&p,&q,&x,&y);
58         int n;
59         ll res1=solve(p+1);
60         ll res2=solve(q+1);
61         scanf("%d",&n);
62         printf("Case #%d:\n",cas++);
63         while(n--){
64             ll a,l=p+1,r=q;
65             scanf("%I64d",&a);
66             a+=res1;
67             if(a<=res1||a>res2){
68                 printf("Nya!\n");
69                 continue;
70             }
71             while(r>l){
72                 ll m=(l+r)>>1;
73                 ll res3=solve(m+1);
74                 if(res3>=a)
75                     r=m;
76                 else
77                     l=m+1;
78             }
79         printf("%I64d\n",r);
80         }
81     }
82     return 0;
83 }
AC Code