hdu 3555 Bomb
Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 4757 Accepted Submission(s): 1652
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
//n++ 枚举上界,处理49、049、0049等重复状态
1 //15MS 252K 1286 B C++ 2 //第一道数位DP,参考别人的思路和代码后写的 3 /* 4 * 1、dp[i][0]代表没有49的情况 XXXXX 5 * dp[i][0]=dp[i-1][0]*10-dp[i-1][1] XXXXX=10*XXXX-X9XXX 6 * 2、dp[i][1]代表第一位数是9的情况 9XXXX 7 * dp[i][1]=dp[i-1][0] 9XXXX=XXXX 8 * 3、dp[i][2]代表有49的情况 X49XX 9 * dp[i][2]=dp[i-1][2]*10+dp[i-1][1] X49XX=49XX+9XXX 10 * 11 * 没有49的情况可以跳转到有一个9的情况,有一个9的情况可以跳转到 12 * 没有49或有49的情况,有49的情况只能跳转到有49的情况。 13 * 14 * 在1中没有49的情况等于 上一状态*10 减去 49XXX的情况 15 */ 16 #include<stdio.h> 17 #include<string.h> 18 __int64 dp[25][3]; 19 int num[25]; 20 void init() 21 { 22 memset(dp,0,sizeof(dp)); 23 dp[0][0]=1; 24 for(int i=1;i<20;i++){ 25 dp[i][0]=dp[i-1][0]*10-dp[i-1][1]; //没有49(XXXXX) 26 dp[i][1]=dp[i-1][0]; //只有9 (9XXXX) 27 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; //有49 (49XXX) 28 //printf("%I64d %I64d %I64d\n",dp[i][0],dp[i][1],dp[i][2]); 29 } 30 } 31 int main(void) 32 { 33 int t; 34 __int64 n; 35 init(); 36 scanf("%d",&t); 37 while(t--) 38 { 39 scanf("%I64d",&n); 40 int k=0; 41 memset(num,0,sizeof(num)); 42 n++; 43 while(n){ 44 num[++k]=n%10; 45 n/=10; 46 } 47 int flag=0; 48 int last=0; 49 __int64 ans=0; 50 for(int i=k;i>0;i--){ //从最高位处理,处理完后没用了 51 ans+=num[i]*dp[i-1][2]; //最高位*49XX 52 if(flag){ //出现49后,处理49XXX情况,XXX为无49状态 53 ans+=dp[i-1][0]*num[i]; 54 } 55 if(!flag && num[i]>4){//处理X9XXX的情况 56 ans+=dp[i-1][1]; 57 } 58 if(last==4 && num[i]==9){ 59 flag=1; 60 } 61 last=num[i]; 62 } 63 printf("%I64d\n",ans); 64 } 65 return 0; 66 }