题意:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3943
在区间[P,Q]中找到第k大的数位上还有x个4以及y个7的数。
思路:
二分+数位dp。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL p, q, x, y, k;
int a[25];
LL dp[25][25][25];
LL dfs(int pos, int four, int seven, bool limit) {
if (pos == -1) return (four == x && seven == y);
if (four > x || seven > y) return 0;
if (!limit && dp[pos][four][seven] != -1) return dp[pos][four][seven];
int up = limit ? a[pos] : 9;
LL res = 0;
for (int i = 0; i <= up; i++) {
res += dfs(pos - 1, four + (i == 4), seven + (i == 7), limit && a[pos] == i);
}
if (!limit) dp[pos][four][seven] = res;
return res;
}
LL cal(LL x) {
int pos = 0;
while (x) {
a[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, 0, 0, true);
}
void solve() {
LL res = -1;
LL l = p + 1, r = q;
while (l <= r) {
LL m = (l + r) >> 1;
if (cal(m) > k) r = m - 1;
else if (cal(m) == k) {
res = m;
r = m - 1;
}
else l = m + 1;
}
printf("%I64d\n", res);
}
int main() {
//freopen("in.txt", "r", stdin);
int T, cs = 0;
scanf("%d", &T);
while (T--) {
int n;
memset(dp, -1, sizeof(dp));
scanf("%I64d%I64d%I64d%I64d%d", &p, &q, &x, &y, &n);
printf("Case #%d:\n", ++cs);
LL xx = cal(p), yy = cal(q);
while (n--) {
scanf("%I64d", &k);
if (k > yy - xx) {
puts("Nya!");
continue;
}
k += xx;
solve();
}
}
return 0;
}