HDU3943 K-th Nya Number 数位DP

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sdz20172133/article/details/82535157

 

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. 

InputThe 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).OutputFor 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!

因为longlong卡了三个小时,心累


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[20];
ll dp[25][25][25];
ll x,y;
ll dfs(int pos,int sta1,int sta2,bool limit)

{
	if(sta1>x||sta2>y) return 0;
    if(pos==-1) return sta1==x&&sta2==y;
    if(!limit && dp[pos][sta1][sta2]!=-1) return dp[pos][sta1][sta2];
    int up=limit ? a[pos] : 9;
	ll tmp=0;
    for(int i=0;i<=up;i++)
    {
    	if(i==4)
		tmp+=dfs(pos-1,sta1+1,sta2,limit && i==a[pos]);
		else if(i==7)
		tmp+=dfs(pos-1,sta1,sta2+1,limit && i==a[pos]);
	    else
		tmp+=dfs(pos-1,sta1,sta2,limit && i==a[pos]);
    }
    if(!limit) dp[pos][sta1][sta2]=tmp;
    return tmp;
}
ll solve(ll x)
{
    int pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,0,true);
}
int main()
{
                        
   

     int T;
    scanf("%d",&T);
    int case1=0;
    while(T--)
    {   case1++;
    	   ll p,q;
        memset(dp,-1,sizeof(dp));
     
        scanf("%I64d%I64d%I64d%I64d",&p,&q,&x,&y);  
	 
	  ll m=solve(q); 
	  ll n=solve(p); //
	  int w;
	  scanf("%d",&w);
	 
	   printf("Case #%d:\n",case1);
	  while(w--)
	  {     
	  	 ll t;
	  	 scanf("%I64d",&t);
	  	 if(t>m-n)
	  	 printf("Nya!\n");
		 else
		 {
		 	ll l=p,r=q,mid;
	        while(l<=r)
	      {
		   mid=(l+r)/2;
		  if(solve(mid)-n>=t)
		   {
			r=mid-1;
		   }
		   else
		  {
			l=mid+1;
		   }
	     }
	     
	     printf("%I64d\n",l); 
		 }
	  }

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sdz20172133/article/details/82535157