hdu 3943

数位dp

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <vector>
#include <sstream>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <iostream>
#define maxn 105
#define INF 0x3f3f3f3f
#define inf 10000000
#define MOD 100000000
#define ULL unsigned long long
#define LL long long
#define _setm(houge) memset(houge, INF, sizeof(houge))
#define _clear(houge) memset(houge, 0, sizeof(houge))
using namespace std;

LL dp[25][25][25], p, q;
int dig[25], x, y;

void init() {
    _clear(dp);
    dp[0][0][0] = 1;
    for(int i = 1; i <= 20; ++ i) {
        for(int j = 0; j <= i; ++ j) {
            for(int k = 0; k+j <= i; ++ k) {
                dp[i][j][k+1] += dp[i-1][j][k];
                dp[i][j+1][k] += dp[i-1][j][k];
                dp[i][j][k] += dp[i-1][j][k]*8;
            }
        }
    }
}

int getdig(LL nx) {
    _clear(dig);
    int cnt = 0;
    while(nx) {
        dig[++cnt] = nx%10;
        nx /= 10;
    }
    return cnt;
}

LL countid(LL nx) {
    int cnt = getdig(nx);
    LL ans = 0;
    int cx = x, cy = y;
    for(int i = cnt; i > 0; -- i) {
        for(int j = 0; j < dig[i]; ++ j) {
            if(j == 4 && cx) ans += dp[i-1][cx-1][cy];
            else if(j == 7 && cy) ans += dp[i-1][cx][cy-1];
            else if(j != 4 && j != 7) ans += dp[i-1][cx][cy]; 
        }
        if(dig[i] == 4) cx --;
        if(dig[i] == 7) cy --;
        if(cx < 0 || cy < 0) break;
    }
    return ans;
}

LL findd(LL k) {
    int len = 1;
    while(!(dp[len-1][x][y] < k && dp[len][x][y] >= k)) ++ len;
    long long res = 0;
    int cx = x, cy = y;
    for(int i = len; i > 0; -- i)
        for(int j = 0; j < 10; ++ j) {
            int tx = cx, ty = cy;
            if(j == 4) {
                -- tx;
                if(tx < 0)
                    continue;
            }
            if(j == 7) {
                -- ty;
                if(ty < 0)
                    continue;
            }
            if(dp[i-1][tx][ty] >= k) {
                res = res*10+j;
                cx = tx;
                cy = ty;
                break;
            }
            k -= dp[i-1][tx][ty];
        }
    return res;
}

int main()
{
    int t, ca = 0;
    init();
    scanf("%d", &t);
    while(t --) {
        scanf("%I64d%I64d%d%d", &p, &q, &x, &y);
        LL a = countid(p+1), b = countid(q+1);
        int n;
        scanf("%d", &n);
        printf("Case #%d:\n", ++ ca);
        while(n --) {
            LL k;
            scanf("%I64d", &k);
            if(k > b-a) puts("Nya!");
            else printf("%I64d\n", findd(k+a));
        }
    }
    return 0;
}

  

posted @ 2014-07-26 14:55  xlc2845  阅读(224)  评论(0编辑  收藏  举报