Problem Description
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.
Author
fatboy_cw@WHU
Source
2010 ACM-ICPC Multi-University Training Contest(12)——Host by WHU
Recommend
zhouzeyong | We have carefully selected several
similar problems for you: 3554 3556 3557 3558 3559
题解
数位DP
设\(f[i][j][0/1]\)为\(i\)位数,最高位为\(j\),是否包含数位串‘ 49’ 的数的个数。
预处理\(f\)数组后进行数位DP。
先填充位数不满的,再由高位向低位将此位不满的加入答案。
统计每一位时考虑先前的位置是否已经出现 ‘49’
转换询问区间为[1,n)[1,n)则更易简单处理。
code
#include <iostream> #include <cstdio> using namespace std; typedef unsigned long long ULL; ULL f[50][50][5], bit[50], t, n; void init() { f[0][0][0] = 1; bit[0] = 1; for(int i = 1;i <= 20;i ++) { bit[i] = bit[i-1] * 10; for(int j = 0;j <= 9;j ++) { for(int k = 0;k <= 9;k ++) { f[i][j][0||(j == 4&&k == 9)] += f[i-1][k][0]; f[i][j][1||(j == 4&&k == 9)] += f[i-1][k][1]; } } } } ULL calc(ULL x) { int pos, last = 0, flag = 0, di = 1; ULL res = 0; for(pos = 1;bit[pos] <= x;pos ++) { for(int j = 1;j <= 9;j ++) { res += f[pos][j][1]; } } for( ; pos ;pos --) { int now = (x / bit[pos-1]) % 10; for(int j = di;j < now;j ++) { res += f[pos][j][1] + f[pos][j][0] * flag; } if(last == 4&&now == 9) flag = 1; last = now; di = 0; } return res; } int main() { init(); cin >> t; while(t --> 0) cin >> n, cout << calc(n + 1) << endl; return 0; }