【HDU】3943-K-th Nya Number-区间dp+二分答案求解

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 3547    Accepted Submission(s): 1147


 

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   |   We have carefully selected several similar problems for you:  3940 3944 3941 3942 3945 

题目大意:给出一个区间【p~q】求出其中的数字中满足有x个4和y个7的个数,并且有排序,因为后面的要输出的是第i个满足这样数字的数是多少

思路:区间dp求解,其中dp[i][j][k]表示i位数字中 有j个4K个7,后面的dfs式子中也会表达

在p和q之间二分,利用查找出来的符合条件的数量减去q的符合条件的数量就是第n大的数,利用二分找出第k大个数。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
#define maxn 22
using namespace std;

int a[maxn];
ll dp[maxn][maxn][maxn];//i位数字中 有j个4K个7
ll x,y;

ll dfs(int pos,int q4,int q7,bool limit)
{
    if(q4>x||q7>y) return 0;
    if(pos==-1) return q4==x&&q7==y;
    if(!limit&&dp[pos][q4][q7]!=-1)
        return dp[pos][q4][q7];
    int up=limit?a[pos]:9;
    ll ans=0;

    for(int i=0;i<=up;i++)
    {
        ans+=dfs(pos-1,q4+(i==4),q7+(i==7),limit&&i==up);
    }
    if(!limit)dp[pos][q4][q7]=ans;
    return ans;
}

ll go(ll x)
{
    int pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,0,1);
}

int main()
{
    int t;cin>>t;
    for(int j=1;j<=t;j++)
    {
        printf("Case #%d:\n",j);
        memset(dp,-1,sizeof(dp));
        ll p,q;
        int n;
        cin>>p>>q>>x>>y;
        cin>>n;
        ll w1=go(q);
        ll w2=go(p);

        while(n--)
        {
            ll k;
            cin>>k;
            if(k>w1-w2)
            {
                cout<<"Nya!"<<endl;
                continue;
            }

            ll l=p,r=q,mid;
            while(l<=r)
            {
                mid=(l+r)/2;
                if(go(mid)-w2<k)
                {
                    l=mid+1;
                }
                else
                    r=mid-1;
            }
            cout<<l<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wentong_Xu/article/details/82670869