2022上海省赛——A. Another A+B Problem

链接:Problem - A - Codeforces

Just before the 2022 Shanghai Collegiate Programming Contest, you decide to play some games to chill out. Today, your friend Tommy introduces a game called Nerdle to you. This game is about to guess some equations.

A game in Nerdle.


You can present an equation to the jury each time. The jury will send back results by the colors:

If it's green, as the +, = and 5 in the first line of the figure, the digit or operator are in the solution and in the correct spot.
If it's purple, as the 4 and the first two 1s in the first line of the figure, the digit is in the solution but in the wrong spot.
If it's black, the digit is not in the solution in any spot, or
If your guess includes a digit that appears more times than it is in the answer, you will get color tiles exactly as the number of appearances in the answer, and the remaining tiles are black. Therefore, the first equation in the figure contains exactly two 1s, but none of them are in the two middle spots and the last spot. Purple and black tiles can be chosen arbitrarily if both exist for a digit.
After playing for a while, you found that you spent a lot of time just trying to make the left-hand side equal to the right-hand side. As a strong competitive programmer, it's so much a waste of time for you. You decide to use your computer to analyze the result of one equation so that the remaining possible equation can be obtained. The equation and answer have the following restrictions:

The third and the sixth character are fixed with '+' and '=' respectively, and they are all green.
The only allowed operator is the binary plus sign. Here, 'binary' is for involving two operands. So, the answer is always in the form "??+??=??" where '?' can be replaced by a digit (0...9).
Leading zeros are allowed here, so "01+02=03" is a valid equation.
Write a program to find out all possible remaining equations by a given result.

Input
The input contains two strings E,C of length 8 in two lines, denoting the equation asked and the color returned by the jury, respectively. C consists of 'GPB', denoting green, purple, and black of the corresponding spot.

It's guaranteed that:

E is a valid equation.
The third and the sixth character of E are fixed with '+' and '=' respectively, and the other positions are digits (0...9).
The third and the sixth character of C are 'G'.

Output
Print an integer R in the first line, denoting the number of different remaining possible equations. Two equations are considered different if they are different on at least one character.

For the next R lines, print a string in each line denoting a valid equation corresponding to the input.

You can print your solution in any order. It's guaranteed that at least one valid equation exists.

Examples

input

40+11=51
PBGPPGGB

output

7
11+42=53
11+43=54
11+44=55
11+45=56
11+46=57
11+47=58
11+48=59

input

12+46=58
GBGGPGGB

output

6
11+45=56
13+43=56
15+41=56
16+40=56
16+41=57
16+43=59

input

11+22=33
PBGPPGGP

output

1
22+13=35

题意:猜方程游戏,给定一个方程,方程中每个字符下面都有一个字符。 
字符G表示这个位置上一定会出现该方程位置上的字符。
字符P表示该方程位置上的字符会出现在方程中,但是不在这个位置
字符B表示该方程位置上的字符不会出现在这个答案的方程中,但如果G或P标记过该字符,那么除了G和P标记的那些字符以外,不能再出现该字符,同时P标记的那个和B标记相同的字符,不能出现该位置上。

比如:图中4和5位置上的1被P标记,位置8上的1被B标记,那么1只能出现两次,同时不能出现在P和这个B标记的位置上。
题目保证字符'+'和'='一定被G标记,方程格式一定是XX+XX=XX的格式(X=0,1,2,..,9),并且允许前导0,如01+02=03。

该题数据不大可以直接暴力,开多个数组分别标记 被P标记的数字出现次数,P和B标记过的地方哪些数字不能出现,被B标记过和被G标记过的。 
然后dfs遍历每个位可能出现的数字,求出所有满足条件的可能. 

代码如下:

#include<iostream>
#include<string>
#include<vector>
#include<cstring>
using namespace std;
string eq, s; //方程字符串和颜色字符串 
vector<string> res; //用来存结果 
int nums[15] {0}; //用来存被P标记过的数字出现次数 
int fg[15][15] {0}; //fg[i][j], 表示i位置上是否可以出现j,可以值为0,不可以则为1 
int Gfg[15], Bfg[15];//Gfg[i]表示i位置上数字是否被G标记,Bfg[i]表示i位置上数字是否被B标记,标记为1否则为0 
void dfs(int now, string ans) //dfs遍历每一种可能,now表示当前位置,ans表示方程 
{
	if(Gfg[now]) //当该位置被G给标记时 
	{
		dfs(now+1, ans+eq[now]); //方程该位置上直接放上给定方程位置上的数
		return; 
	}
	if(now==eq.size()) //当该方程此处遍历完成时 
	{
		for(int i=0; i<=9; i++) //如果存在P标记的数没有用完,该方程不合格,直接返回 
			if(nums[i])
				return; 
		int a = (ans[0]-'0')*10+ans[1]-'0', b = (ans[3]-'0')*10+ans[4], c = (ans[6]-'0')*10+ans[7]; //计算方程式结果 
		if(a+b!=c) return; //方程式结果不匹配,返回 
		res.push_back(ans); //存入该方程答案 
		return;
	}
	for(int i=0; i<=9; i++) //遍历0~9的 
	{
		if(fg[now][i]  || Bfg[i] && !nums[i]) continue; //当该位置不能出现这个数,或者该数被B标记时,跳过 
		else
		{
			if(nums[i]) //如果该数是被P标记 
			{
				nums[i] --;
				dfs(now+1, ans+char(i+'0'));
				nums[i] ++;
			}
			else dfs(now+1, ans+char(i+'0'));
		}
	}
}
int main()
{
	cin >> eq >> s;
	for(int i=0; i<eq.size(); i++)
	{
		if(s[i]=='P')
			nums[eq[i]-'0'] ++, fg[i][eq[i]-'0'] = 1;
		else if(s[i]=='B')
			fg[i][eq[i]-'0'] = 1, Bfg[eq[i]-'0'] = 1;
		else if(s[i]=='G')
			Gfg[i] = 1;
	}
	dfs(0, "");
	cout << res.size();
	puts("");
	for(int i=0; i<res.size(); i++)
		cout << res[i] << "\n"; 
	return 0;
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值