1. 程式人生 > >【HDU3943】【K-th Nya Number】【數位+二分找位置】

【HDU3943】【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): 2493    Accepted Submission(s): 770

Problem DescriptionArcueid 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 Input1 38 400 1 1 10 1 2 3 4 5 6 7 8 9 10
Sample OutputCase #1: 47 74 147 174 247 274 347 374 Nya! Nya!
Authorhzhua
Source
#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;
    
typedef long long ll;
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)
{
	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);
	}
	return flag ? res : dp[len][c4][c7] = 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 = 1;
    scanf("%d",&T);
	while(T --)
	{
		printf("Case #%d:\n",C++);
		memset(dp,-1,sizeof(dp));
		scanf("%I64d%I64d%I64d%I64d",&P,&Q,&X,&Y);
		ll dn = solve(P);
		ll up = solve(Q);

		scanf("%d",&N);
		while(N--)
		{
			ll m;
			scanf("%I64d",&m);
			ll l = P + 1;
		    ll r = Q;
			if(m > up -dn) 
			{
				printf("Nya!\n");
				continue;
			}
			while(l < r)
			{
				ll mid = (l + r) / 2;
				ll s = solve(mid);
				s - dn >= m ? (r = mid) : (l = mid + 1);
			}	
			printf("%I64d\n",l);
		}

	}
    return 0;
}