Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 12924 Accepted Submission(s): 4620
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
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
//题意:
给你一个数N,问你从1---N之间有几个数含有49.
//思路:
先打表,将可能出现的情况数存起来:
dp[i][0]表示前i位有49的情况数;
dp[i][1]表示前i位没有49并且第一位的数为9的情况数;
dp[i][2]表示前i位没有49并且第一位不是9的情况数;
然后从高位向下模拟累加,已经枚举过的位默认为该位最大值。当前位最大值为x,我们就算填0..x-1的方案,首先有x*dp[i][0],即这位填0..x-1乘以之后位含49的方案。如果这一位大于4,我们可以填4,下一位填9。如果这位和之前一位组成了49,那么之后0..之后最大值都是含49的,加上就可以。
具体看代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define ll long long
#define N 110
using namespace std;
int a[N];
ll dp[N][3];
ll n;
int init()//打表
{
dp[0][2]=1;
for(int i=1;i<=24;i++)
{
dp[i][0]=dp[i-1][0]*10+dp[i-1][1];
dp[i][1]=dp[i-1][1]+dp[i-1][2];
dp[i][2]=dp[i-1][1]*8+dp[i-1][2]*9;
}
}
int main()
{
int t,i,j,k;
init();
scanf("%d",&t);
while(t--)
{
int cnt=0;
scanf("%lld",&n);
while(n)
{
a[cnt++]=n%10;
n=n/10;
}
a[cnt]=0;
ll ans=0;
for(int i=cnt-1;i>=0;i--)
{
if(!a[i])
continue;
ans+=dp[i][0]*a[i];
if(a[i]>4)
ans+=dp[i][1];
if(a[i+1]==4&&a[i]==9)
{
ll tmp=0;
for(int j=i-1;j>=0;j--)
tmp=tmp*10+a[j];
ans+=tmp+1;
break;
}
}
printf("%lld\n",ans);
}
return 0;
}