hdu 3943 K-th Nya Number

K-th Nya Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 1619 Accepted Submission(s): 523


Problem Description
Arcueid likes nya number very much.
A nya number is the number which has exactly X fours and Y sevens(If X=2 and Y=3 , 172441277 and 47770142 are nya numbers.But 14777 is not a nya number ,because it has only 1 four).
Now, Arcueid wants to know the K-th nya number which is greater than P and not greater than Q.


Input
The first line contains a positive integer T (T<=100), indicates there are T test cases.
The second line contains 4 non-negative integers: P,Q,X and Y separated by spaces.
( 0<=X+Y<=20 , 0< P<=Q <2^63)
The third line contains an integer N(1<=N<=100).
Then here comes N queries.
Each of them contains an integer K_i (0<K_i <2^63).


Output
For each test case, display its case number and then print N lines.
For each query, output a line contains an integer number, representing the K_i-th nya number in (P,Q].
If there is no such number,please output "Nya!"(without the quotes).


Sample Input
1
38 400 1 1
10
1
2
3
4
5
6
7
8
9
10


Sample Output
Case #1:
47
74
147
174
247
274
347
374
Nya!
Nya!


Author
hzhua


Source
2011 Multi-University Training Contest 11 - Host by UESTC


Recommend
xubiao

 

//不错的数位DP

 1 //562MS    336K    1581 B    C++
 2 /*
 3 
 4 题意: 求(p,q]中第m个Nya数。
 5  
 6     记忆化搜索解数位DP+二分求解,
 7     效率不是很高,但是还是可以接受。 
 8     一开始不知道怎么求第k个符合条件的数,如果先处理了(0~p)和
 9  (0~q)的话,再暴力去找可能会超时,然后看了别人的方法,二分!
10  我竟然没想到,弱爆了,二分虽然还是挺暴力,不过不会TLE。
11  代码优化一下应该可以降低点耗时,不过做出来挺满足了。 
12 
13 */
14 #include<stdio.h>
15 #include<string.h>
16 __int64 dp[20][20][20];
17 int digit[20];
18 __int64 x,y,p,q;
19 __int64 dfs(int pos,int pre4,int pre7,bool judge) //记忆化搜索 
20 {
21     if(pos==-1 || pre4>x || pre7>y) return pre4==x&&pre7==y;
22     if(!judge && dp[pos][pre4][pre7]!=-1)
23         return dp[pos][pre4][pre7];
24     __int64 ans=0;
25     int end=judge?digit[pos]:9;
26     for(int i=0;i<=end;i++){
27         int tpre4=pre4;
28         int tpre7=pre7;
29         if(i==4) tpre4++;
30         if(i==7) tpre7++;
31         ans+=dfs(pos-1,tpre4,tpre7,judge&&i==end);
32     } 
33     if(!judge) dp[pos][pre4][pre7]=ans;
34     return ans;
35 } 
36 __int64 deal(__int64 n) //处理模块 
37 {
38     int pos=0;
39     while(n){
40         digit[pos++]=n%10;
41         n/=10;
42     }
43     return dfs(pos-1,0,0,true);
44 }
45 __int64 get(__int64 m,__int64 tp)//二分求第k个 
46 {
47     __int64 l=p+1,r=q,mid,ans=-1,ret;
48     while(l<=r){
49         mid=(l+r)>>1;
50         ret=deal(mid);
51         if(ret-tp>=m){
52             ans=mid;
53             r=mid-1;
54         }else l=mid+1;
55     }
56     return ans;
57 }
58 int main(void)
59 {
60     int t;
61     int k=1;
62     __int64 n,m;
63     scanf("%d",&t);
64     while(t--){
65         scanf("%I64d%I64d%I64d%I64d",&p,&q,&x,&y);
66         scanf("%I64d",&n);
67         printf("Case #%d:\n",k++);
68         memset(dp,-1,sizeof(dp));
69         __int64 tp=deal(p);
70         __int64 tq=deal(q);
71         //printf("%I64d %I64d\n",tp,tq);
72         while(n--){
73             scanf("%I64d",&m);
74             if(m>tq-tp) puts("Nya!");
75             else printf("%I64d\n",get(m,tp));
76         }
77     }
78     return 0;
79 }

 

posted @ 2013-10-06 10:47  heaventouch  阅读(167)  评论(0编辑  收藏  举报