您的位置:首页 > 其它

hdu---(3555)Bomb(数位dp(入门))

2014-09-28 00:28 435 查看

Bomb

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 7921 Accepted Submission(s): 2778


[align=left]Problem Description[/align]
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?

[align=left]Input[/align]
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.

[align=left]Output[/align]
For each test case, output an integer indicating the final points of the power.

[align=left]Sample Input[/align]

3
1
50
500

[align=left]Sample Output[/align]

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.

[align=left]Author[/align]
fatboy_cw@WHU

[align=left]Source[/align]
2010 ACM-ICPC Multi-University Training Contest(12)——Host by WHU

题意: 给你一个数n,要你统计出1到n中出现含有49数字的个数: 比如 498,549,49.....
对于这一道题: 看到一个博客引用了这张图片,觉得说的很清晰,就引用了..

//#define LOCAL
#include<cstdio>
#include<cstring>
#define LL __int64
using namespace std;
const int maxn=25;
LL dp[maxn][3]={0};
int nn[maxn];
int main()
{

#ifdef LOCAL
freopen("test.in","r",stdin);
#endif
int cas,i;
LL n;
scanf("%d",&cas);
/*数位DP的惯有模式预处理*/
dp[0][0]=1;
for(i=1;i<=20;i++)
{
dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
dp[i][1]=dp[i-1][0];
dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
}
while(cas--)
{
scanf("%I64d",&n);
i=0;
n+=1;
memset(nn,0,sizeof(nn));
while(n>0)
{
nn[++i]=n%10;
n/=10;
}
LL ans=0;
bool tag=0;
int num=0;
for(  ; i>=1  ; i--  )
{
ans+=dp[i-1][2]*nn[i];  /*计算49开头的个数*/
if(tag){
ans+=dp[i-1][0]*nn[i];   /*当前面出现了49的时候,那么后面出现的任何数字也要进行统计*/
}
if(!tag&&nn[i]>4)
{
ans+=dp[i-1][1];      /*如果没有出现49开头,只要首部大于5,那么必定保函有一个49*/
}
if(num==4&&nn[i]==9)
tag=1;
num=nn[i];
}
printf("%I64d\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: