The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
Input
The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.
The input terminates by end of file marker.
Output
For each test case, output an integer indicating the final points of the power.
Sample Input
3
1
50
500
Sample Output
0
1
15
Hint
From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499",
so the answer is 15.
求1~n中含有“49”的数的个数
思路1:前面“不要62”那道题知道了怎么求0~n不含62的数的个数怎么求,改一改求不含49的数的个数,再用n+1-solve(n)
注意:solve(n)求的是0~n中不含49的个数
注意这道题的数据范围,long long
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int a[30];
ll dp[30][2];
ll dfs(int pos,int pre,int sta,bool limit){
if(pos==0) return 1;
if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
int up=limit?a[pos]:9;
ll tmp=0;
for(int i=0;i<=up;i++){
if(pre==4&&i==9) continue;
tmp+=dfs(pos-1,i,i==4,limit&&i==a[pos]);
}
if(!limit) dp[pos][sta]=tmp;
return tmp;
}
ll solve(ll x){
int pos=0;
while(x){
a[++pos]=x%10;
x/=10;
}
return dfs(pos,-1,0,true);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n;
scanf("%lld",&n);
memset(dp,-1,sizeof(dp));
printf("%lld\n",n+1-solve(n));
}
return 0;
}
思路2:直接求含49的数的个数
dp[i][0]:长度为i但是不包含49的方案数
dp[i][1]:长度为i且不含49但是最后一位是4的方案数
dp[i][2]:长度为i且包含49的方案数
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int a[30];
ll dp[30][3];
ll dfs(int pos,int sta,bool limit){
if(pos==0) return sta==2;
if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
int up=limit?a[pos]:9;
ll tmp=0;
for(int i=0;i<=up;i++){
if(sta==2||(sta==1&&i==9))
tmp+=dfs(pos-1,2,limit&&i==a[pos]);
else if(i==4)
tmp+=dfs(pos-1,1,limit&&i==a[pos]);
else
tmp+=dfs(pos-1,0,limit&&i==a[pos]);
}
if(!limit) dp[pos][sta]=tmp;
return tmp;
}
ll solve(ll x){
int pos=0;
while(x){
a[++pos]=x%10;
x/=10;
}
return dfs(pos,0,true);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n;
scanf("%lld",&n);
memset(dp,-1,sizeof(dp));
printf("%lld\n",solve(n));
}
return 0;
}