HDU3555 Bomb(数位dp)

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

题意:计算一个数内含连续数49的个数


思路

    :和上一篇博客题意相近,同理可解,数据很大,要用__int64



#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>


#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
typedef __int64 ll;

#define fre(i,a,b)  for(i = a; i < b; i++)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d%d", &a, &b)
#define sfff(a,b,c) scanf("%d%d%d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 22

ll dp[N][3];

//dp[i][0] 没有不吉利
//dp[i][1] 没有不吉利 首位 为 9
//dp[i][2] 有不吉利

void inint()
{
	dp[0][0]=1;
	ll i;

	for(i=1;i<N;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];
	}
}

void solve(ll x)
{
	ll i,len=0,bit[N];

	while(x)
	{
		bit[++len]=x%10;
		x=x/10;
	}

	bit[len+1]=0;

	ll ans=0;

	bool flag=false;

	for(i=len;i>=1;i--)
	{

		ans+=bit[i]*dp[i-1][2];

		if(flag)
			ans+=bit[i]*dp[i-1][0];

		if(flag)  continue;

		if(bit[i]>4)
			ans+=dp[i-1][1];

		if(bit[i+1]==4&&bit[i]==9)
			flag=true;

	}

	printf("%I64d\n",ans);
}

int main()
{
	int t;
	ll le;
	inint();
	sf(t);
	while(t--)
	{
		scanf("%I64d",&le) ;
		solve(le+1);
	}
	return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值