/*
题目大意:求1 - n范围内含有"49"的数的个数。
思路:记忆化搜索
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
using namespace std;
const int NUMBER_LEN = 19;
const int INDEX_LEN = 10;
int cases, tot; //测试样数,tot数的长度
int num[NUMBER_LEN]; //储存每一位
long long n;
__int64 dp[NUMBER_LEN][INDEX_LEN][2];
void init() //计算每一位数,1 <= n <= 2^63 - 1;
{
memset(dp, 0, sizeof(dp));
tot = 0;
while (n)
{
num[tot++] = n % 10;
n /= 10;
}
}
__int64 solve(int pos, int pre, int flag, bool limit)
{
if (pos <= -1) return flag; //最后一位也搜索结束,返回flag(flag标记是否在之前出现了49)
if (dp[pos][pre][flag] && !limit) return dp[pos][pre][flag]; //如果这种状态已经搜索过,返回结果
int x = limit ? num[pos] : 9; //取上限
__int64 res = 0; //计算结果
for (int i = 0; i <= x; i++)
{
res += solve(pos - 1, i, (pre == 4 && i == 9) || flag, (limit && i == x));
}
if (!limit) dp[pos][pre][flag] = res; //记录结果
return res;
}
void input()
{
scanf("%d", &cases);
while (cases--)
{
scanf("%I64d", &n); //输入
init(); //初始化
cout << solve(tot - 1, 0, 0, 1) << endl; //输出结果
}
}
int main()
{
input();
return 0;
}
hdu3555
最新推荐文章于 2021-07-08 09:39:09 发布