#108-【数位DP】Bomb

Description

反恐怖主义分子在尘土中发现了一枚计时炸弹。 但是这次恐怖分子改进了定时炸弹。 计时炸弹的数字序列从1到N.如果当前数字序列包含子序列“49”,爆炸的力量将增加一点。

现在反恐怖主义分子知道数字N, 他们想要知道威力的最终点。 你能帮助他们吗?

 

Input

第一行输入由整数T(1 <= T <= 10000)组成,表示测试用例数。 对于每个测试用例,将会有一个整数N(1 <= N <= 2 ^ 63-1)作为描述。输入以文件标记的末尾终止。

 

Output

对于每个测试用例,输出指示功率的最终点的整数。

 

Sample Input

3
1
50
500

Sample Output

0
1
15

很模板

// 和不要62是同一个难度等级

#include 
#include 

#define SIZE 110

using namespace std;

long long dp[SIZE][2];
short a[SIZE];

long long dfs(int pos, bool is4, bool havelimit) // 数位DP
{
	long long res = 0;
	int i, len;
	
	if (!pos)
	{
		return 1;
	}
	if ((!havelimit) && (~dp[pos][is4]))
	{
		return dp[pos][is4];
	}
	len = (havelimit) ? a[pos] : 9;
	for (i = 0; i <= len; ++i)
	{
		if ((is4) && (i == 9)) // 包含了49
		{
			continue;
		}
		res += dfs(pos - 1, i == 4, ((havelimit) && (i == len)));
	}
	if (!havelimit)
	{
		dp[pos][is4] = res;
	}
	
	return res;
}

long long doit(int n)
{
	long long pos = 0;
	
	while (n)
	{
		a[++pos] = n % 10;
		n /= 10;
	}
	
	return dfs(pos, false, true);
}

int main(int argc, char** argv)
{
	long long a;
	int t;
	
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &a);
		memset(dp, -1, sizeof (dp));
		printf("%lld\n", a + 1 - doit(a)); // 那么运算结果就是包含49的数字的个数
	}
	
	return 0;
}

 

你可能感兴趣的:(刷题,gdgzoi刷题)