[dfs]Divisible by Twenty-Five Codeforces1575D

Mr. Chanek has an integer represented by a string ss. Zero or more digits have been erased and are denoted by the character _. There are also zero or more digits marked by the character X, meaning they're the same digit.

Mr. Chanek wants to count the number of possible integer ss, where ss is divisible by 2525. Of course, ss must not contain any leading zero. He can replace the character _ with any digit. He can also replace the character X with any digit, but it must be the same for every character X.

As a note, a leading zero is any 0 digit that comes before the first nonzero digit in a number string in positional notation. For example, 0025 has two leading zeroes. An exception is the integer zero, (0 has no leading zero, but 0000 has three leading zeroes).

Input

One line containing the string ss (1≤|s|≤81≤|s|≤8). The string ss consists of the characters 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, and X.

Output

Output an integer denoting the number of possible integer ss.

Examples

input

25

output

1

input

_00

output

9

input

_XX

output

9

input

0

output

1

input

0_25

output

0

Note

In the first example, the only possible ss is 2525.

In the second and third example, s∈{100,200,300,400,500,600,700,800,900}s∈{100,200,300,400,500,600,700,800,900}.

In the fifth example, all possible ss will have at least one leading zero.

题意: 给出一个待匹配的字符串,'_'和'X'代表该位置可以是任何数字,不过每一个'X'表示数字都应相同,但每一个'_'代表数字可以不同,询问有多少种方案使得最终数字为25的倍数且数字中不出现前导零。

分析: 数据量比较小,可以暴搜,对于每一个'_'和'X'直接枚举,但是枚举过'X'的值后,后续所有'X'都是一个定值了,所以可以开flag记录是否枚举过'X'以及枚举后的值是多少,另外还需要考虑前导零的情况,如果数字长度大于1,枚举第一位时只能取1~9,如果等于1,第一位可以取0~9。最后特判一下第一位本来就是'0'的非法情况。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

string s;
int ans;

void dfs(int now, int flag, int num)
{
	if(now == s.size())
	{
		if(num % 25 == 0)
			ans++;
		return;
	}
	if(s[now] != '_' && s[now] != 'X')
		dfs(now+1, flag, num*10+s[now]-'0');
	else if(s[now] == '_')
	{
		//避免出现前导零,需要设置枚举下界 
		int down = 0;//枚举下界 
		if(now == 0 && s.size() > 1)//如果数字长度大于1且枚举的是第1位 
			down = 1; 
		for(int i = down; i <= 9; i++)
			dfs(now+1, flag, num*10+i);
	}
	else
	{
		if(flag != -1)
			dfs(now+1, flag, num*10+flag);
		else
		{
			int down = 0;
			if(now == 0 && s.size() > 1)
				down = 1; 
			for(int i = down; i <= 9; i++)
				dfs(now+1, i, num*10+i);
		}
	}
}

signed main()
{
	cin >> s;
	if(s[0] == '0' && s.size() > 1)
		puts("0");
	else
	{
		dfs(0, -1, 0);	
		printf("%d", ans);
	}
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值