数位dp。
给一个N
,问你从[1,N]
中包含49
的数的个数。
主要有两点。
solve(x)
求的是[0,x]
中不包含49
的个数(一检测到“49”就continue
了)- 这题要用
__int64
,这玩意linux还用不了,所以定义一个typedef
是好习惯,方便改。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
using namespace std; // 数位dp模板
typedef __int64 ll; // 视运行环境而定
ll N;
int T;
int num[30];
ll dp[30][2];
ll dfs(int pos, int status, bool limit)
{
//printf("dfs(%d, %d, %s)\n", pos, status, limit ? "true" : "false");
if (pos == -1) return 1;
if ((!limit) && dp[pos][status] != -1) return dp[pos][status];
ll cnt = 0;
int up = (limit ? num[pos] : 9);
for (int i = 0; i <= up; i++)
{
if ((status == 1) && i == 9) continue;
cnt += dfs(pos - 1, i == 4 ? 1 : 0, limit && (i == up));
}
if (!limit) dp[pos][status] = cnt;
return cnt;
}
ll solve(ll x)
{
int pos = 0;
for (; x;)
{
num[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, 0, true);
}
int main()
{
scanf("%d", &T);
memset(dp, -1, sizeof dp); //
for (; T--;)
{
scanf("%I64d", &N);
printf("%I64d\n", N + 1 - solve(N)); // 因为solve把0也算进去了
}
return 0;
}