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 }