yusijia’s blog hdu 3555

和hdu2089差不多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54


#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

long long dp[25][3];

//dp[i][1]表示符合的数且最高位为9
//dp[i][2]表示不符合的数

void ()
{
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(int i = 1; i <= 22; i++){
dp[i][0] = dp[i - 1][0] * 10 - dp[i - 1][1];//减去开头为9的情况
dp[i][1] = dp[i - 1][0];//开头为9的数
dp[i][2] = dp[i - 1][2] * 10 + dp[i - 1][1];//后面加的是开头为9的,因为可能补个4
}
}

long long solve(long long n)
{
long long len = 0, a[25], flag = 0, ans = 0;
while(n){
a[++len] = n % 10;
n /= 10;
}
for(int i = len; i >= 1; 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(a[i + 1] == 4 && a[i] == 9)
flag = 1;
}
return ans;
}

int main()
{
int t;
long long n;
init();
scanf("%d", &t);
while(t--){
scanf("%I64d", &n);
printf("%I64dn", solve(n + 1));
}
return 0;
}