Time Limit:1000MS | Memory Limit:65536KB | 64bit IO Format:%I64d & %I64u |
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?
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.
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. 这是我写的第一道数位DP的题目,看了kuangbin大神的数位dp很久,才明白怎么写数位DP,看来脑洞还是太小了,还得努力啊!/****************************************************** / /* /* * *********** * * * Auther: ZSGG * * * * * * Name: * * * * * *********** Algorithm: * * * */ /*******************************************************/ #include #include #include #include #include
#include #include #include #include #define ls u << 1 #define rs u << 1 | 1 #define lson l, mid, u << 1 #define rson mid + 1, r, u << 1 | 1 using namespace std; typedef long long ll; ll dp[25][3]; void init() { dp[0][0] = 1; //表示位数为i的无49的个数; 等于1是为首位为9,位数为1的数服务; dp[0][1] = 0; //表示位数为i的无49的个数但最高位为9的个数; dp[0][2] = 0; //表示位数为i的含有49的个数; for(int i = 1; i < 25; 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]; //加上没含49但最高位是9的个数(加上4就成49了); } } ll solve(ll n) { ll ans = 0; bool vis = false; int bit[25],tot = 0; while(n) { bit[++tot] = n % 10; n /= 10; } bit[tot + 1] = 0; for(int i = tot; i >= 1; i--) { ans += dp[i - 1][2] * bit[i]; if(vis) ans += bit[i] * dp[i - 1][0]; // 这一步和下一步要细心体会其中的高深之处,看了kuangbin大神的代码好久才明白这个道理; else if(bit[i] > 4) ans += dp[i - 1][1]; //如果n本身已经含有49了就不用考虑是否最高位为9了,直接加上没49的个数,因为n含了49 if(bit[i + 1] == 4 && bit[i] == 9) vis = true; } if(vis) ans++; //如果n本身也包含49,则要加1; return ans; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); ll n; int t; init(); scanf("%d", &t); while(t--) { scanf("%I64d",&n); printf("%I64d\n",solve(n)); } return 0; }