数位DP
d[len][num] 表示长度为len+1,前一位是否为4(num==1或0)的数到0之间有多少个符合条件的数(不含49)
最后用n减去结果就是答案
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=20;
ll d[N][2];
int dis[N];
ll dp(int len,int num,bool flag)
{
if(len==-1) return 1;
if(!flag&&d[len][num]!=-1) return d[len][num];
ll ans=0;
int end=flag?dis[len]:9;
for(int i=0;i<=end;i++)
{
if(num==1&&i==9) continue;
ans+=dp(len-1,i==4,flag&&i==end);
}
if(!flag) d[len][num]=ans;
return ans;
}
ll solve(ll n)
{
int t=0;
while(n)
{
dis[t++]=n%10;
n/=10;
}
return dp(t-1,0,true);
}
int main()
{
memset(d,-1,sizeof(d));
int T;
ll n;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
printf("%lld\n",n-solve(n)+1); //最后要加一,因为没有0
}
return 0;
}