http://acm.hdu.edu.cn/showproblem.php?pid=3555
#include <stdio.h>
#define M 25
__int64 dp[M][3]; //dp[i][0] 位数为i 不含49的个数
//dp[i][1] 位数为i 不含49的个数 但是尾数为9
//dp[i][2] 位数为i 含49的个数
int num[M];
int main()
{
__int64 n;
int t,i,j,k,len;
scanf("%d",&t);
dp[0][0]=1;
for(i=1;i<=M;i++)
{ // 减去第i位添加4 第i-1位为9的个数
dp[i][0]=10*dp[i-1][0]-dp[i-1][1];
dp[i][1]=dp[i-1][0]; // i-1位 不含49个数 第i位添加一个9
dp[i][2]=10*dp[i-1][2]+dp[i-1][1]; // i-1位数的个数含(49)×10(尾数有10种可能)+ 第i-1位数为9(i-1)位中不含49 第i位添加4
}
while(t--)
{
scanf("%I64d",&n);
len=0;
n++;// 处理最低两位为49的情况
while(n)
{
num[++len]=n%10;
n=n/10;
}
__int64 ans=0;
int flag,last;
flag=last=0;
for(i=len;i>=1;i--)
{
ans+=dp[i-1][2]*num[i];
if(flag)
{
ans+=dp[i-1][0]*num[i]; // 有2个高位就是49
}
if(!flag&&num[i]>=5) //最高位大于等于5 则低一位一定有9存在
{
ans+=dp[i-1][1];
}
if(last==4&&num[i]==9)
{
flag=1;
}
last=num[i];//高位
}
printf("%I64d\n",ans);
}
return 0;
}