K-th Nya Number

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!

思路:

#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
int T;
ll P,Q,X,Y;
int N;
int bits[70];
ll dp[70][70][70];

ll dfs(int len,int c4,int c7,bool flag)  //分别表示,还有多少没取得位数,4的个数,7的个数,有没有上限。
	//if(c4 > X || c7 > Y) return 0;
	if(len <= 0) return c4 == X && c7 == Y;
	if(!flag && dp[len][c4][c7] != -1) return dp[len][c4][c7];
	int end = flag ? bits[len] : 9;
	ll res  = 0;
	for(int i=0;i<=end;i++)
	{
		if(i == 4)
		res += dfs(len-1,c4+1,c7,flag && i == end);
		else if(i == 7)
		res += dfs(len-1,c4,c7+1,flag && i == end);
		else
		res += dfs(len-1,c4,c7,flag && i == end);
	}
	if(!flag)
        dp[len][c4][c7] = res;
    return res;
}

ll solve(ll x)
{
	int c = 0;
	ll tt = x;
	while(tt > 0)
	{
		bits[++c] = tt % 10;
		tt /= 10;
	}
	return dfs(c,0,0,true);
}
int main()
{
	int c = 0;
    scanf("%d",&T);
	while(T --)
	{ c++;
		cout<<"Case #"<<c<<":"<<endl;
		memset(dp,-1,sizeof(dp));
		cin>>P>>Q>>X>>Y;
		ll a = solve(P);
		ll b = solve(Q);
        cin>>N;

		while(N--)
		{
			ll m;

			cin>>m;
			ll l = P;
		    ll r = Q;
			if(m > b-a)
			{
				cout<<"Nya!"<<endl;

			}
			else{
			while(l<r)//这里是二分查找。
               {
                   ll mid=(l+r)/2;
                if(solve(mid)-a>=m)
                {
                    r=mid;
                }
                else
                {
                    l=mid+1;
                }
               }
               cout<<l<<endl;
			}
		}

	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40859951/article/details/82531065