Title link: HDU3555 Bomb
Question meaning: ask the number of 49 in 1~n;
Analysis: First use init() to find out how many of the n-digit numbers contain 49;
dp[i[[j] is used to store the number of qualified numbers i represents the length of the currently processed number is i; here the number processed by dp[i][j] can contain leading zeros;
dp[i][0] represents the number that does not contain 49 in the number of length i;
dp[i][1] represents the number of numbers with a length of i that do not contain 49 but the highest digit is 9;
dp[i][2] represents the number of numbers containing 49 in the number of length i;
Then start to find how many numbers less than the given number contain 49;
Scan backwards, when the len position is reached, the len position is the largest number that can be placed before the given number (that is, a[i]), and the len position is less than the given number (that is, a[i]);
#include<iostream>
#include<cstring>
#include<string.h>
#include<cmath>
#include<algorithm>
#define ll long long int
#define ull unsigned long long int
using namespace std;
int a[25];
ll dp[21][3];
int t;
ull n;
int main()
{
scanf("%d",&t);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for (int i=1;i<21;i++)
{
dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
dp[i][1]=dp[i-1][0];
dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
}
while (t--)
{
scanf("%llu",&n);
int len=0;
memset(a,0,sizeof(a));
n++;
while (n)
{
a[++len]=n%10;
n/=10;
}
ll ans=0;
int last=0;
bool flag=false;
for (int i=len;i>0;i--)
{
ans+=(dp[i-1][2]*a[i]);
if (flag) ans+=dp[i-1][0]*a[i];
if (!flag && a[i]>4) ans+=dp[i-1][1];
if (last==4 && a[i]==9) flag=true;
last=a[i];
}
printf("%lld\n",ans);
}
return 0;
}