蓝桥杯-My bad

如题,算法不麻烦,写得有点麻烦,这题需要考虑好用什么数据结构,怎么存这么多的输入。
我用的是类,门类,一个门对应一个门对象,变量有类型、输入来源、输出、方法有计算输出,参数为输入来源的输入。
计算输出时,电路输入可直接进行计算,门输入还要先计算该门的输出,用到了DFS;最后打印错误信息时,需要考虑清楚错误产生的原因,一个门可能有2种错误,即全反+全0/全1,若存在多个错误信息那就意味着无法诊断:

#include<bits/stdc++.h>

using namespace std;

class gate {
public:
	gate(void) {}
	char type; //门的类型
	vector<string> from; //输入来源,非门只有一个输入,其他两个
	bool out = 0; //输出一个

	void settype(char t) {
		this->type = t;
	}
	void setfrom(vector<string> i) {
		this->from = i;
	}
	bool setout(vector<bool> i) {
		if (type == 'n') {
			this->out = !i[0];
			return !i[0];
		}
		else if (type == 'a') {
			if (i[1] == 1 && i[0] == 1) {
				this->out = 1;
				return 1;
			}
			else this->out = 0;
		}
		else if (type == 'o') {
			if (i[1] == 1 || i[0] == 1) {
				this->out = 1;
				return 1;
			}
			else this->out = 0;
		}
		else if (type == 'x') {
			if ((i[1] == 0 && i[0] == 1) || (i[1] == 1 && i[0] == 0)) {
				this->out = 1;
				return 1;
			}
			else this->out = 0;
		}
		return 0;
	}
};

vector <gate> Gate;
int n, g, u; //输入数、门数、输出数

vector<int> counts;

void dfs(bool in[10], int i) //参数1为原始电路输入,参数2为门编号
{
	if (counts.size() == g) //遍历了所有门
		return;

	//若已遍历则退出
	for (int j = 0; j < counts.size(); j++)
	{
		if (counts[j] == i)
			return;
	}

	counts.resize(counts.size() + 1);
	counts[counts.size() - 1] = i;

	if (Gate[i].from.size() == 1) //非门,一个输入来源
	{
		if (Gate[i].from[0].at(0) == 'i') //如果为电路输入,则找到该输入对应的编号直接计算 
			Gate[i].setout({ in[Gate[i].from[0].at(1) - '1'] });
		else //如果是门输入,则要先计算前门的输出
		{
			dfs(in, Gate[i].from[0].at(1) - '1');
			Gate[i].setout({ Gate[Gate[i].from[0].at(1) - '1'].out }); //前门输出计算完毕,那么setout的参数就为前门的输出
		}
		return;
	}
	else //其他三门
	{
		bool a = 0, b = 0;
		if (Gate[i].from[0].at(0) == 'i' && Gate[i].from[1].at(0) == 'i') //如果两个输入都为电路输入 
		{
			a = in[Gate[i].from[0].at(1) - '1']; b = in[Gate[i].from[1].at(1) - '1'];
		}
		else if (Gate[i].from[0].at(0) == 'g' && Gate[i].from[1].at(0) == 'i')//如果第一个输入为门输入,则要先计算前门的输出
		{
			dfs(in, Gate[i].from[0].at(1) - '1');
			a = Gate[Gate[i].from[0].at(1) - '1'].out;
			b = in[Gate[i].from[1].at(1) - '1'];
		}
		else if (Gate[i].from[1].at(0) == 'g'&& Gate[i].from[0].at(0) == 'i')//如果第二个输入为门输入
		{
			dfs(in, Gate[i].from[1].at(1) - '1');
			a = in[Gate[i].from[0].at(1) - '1'];
			b = Gate[Gate[i].from[1].at(1) - '1'].out;
		}
		else //两个都为门输入
		{
			dfs(in, Gate[i].from[1].at(1) - '1');
			dfs(in, Gate[i].from[0].at(1) - '1');
			a = Gate[Gate[i].from[0].at(1) - '1'].out;
			b = Gate[Gate[i].from[1].at(1) - '1'].out;
		}
		//两个输入确定后,设置该门输出
		Gate[i].setout({ a,b });
		return;
	}
}




int main()
{
	int turn = 1;
	while (cin >> n >> g >> u && (n != 0 || g != 0 || u != 0)) {
		//输入门的信息
		Gate.resize(g);
		vector<string> from;
		char type;
		for (int i = 0; i < g; i++)
		{
			cin >> type;
			if (type == 'n')
			{
				from.resize(1);
				cin >> from[0];
			}
			else {
				from.resize(2);
				cin >> from[0] >> from[1];
			}
			Gate[i].settype(type);
			Gate[i].setfrom(from);
		}
		vector<int> index(u); //各个输出对应的门编号
		for (int i = 0; i < u; i++)
			cin >> index[i];

		int b; cin >> b;
		bool in[10][10]; //原始输入
		bool out[10][20]; //实际输出,即题目给出的输出
		bool out_ture[10][20]; //理论输出,即根据输入计算而来的输出
		for (int i = 0; i < b; i++)
		{
			for (int j = 0; j < n; j++)
				cin >> in[i][j];
			for (int j = 0; j < u; j++)
				cin >> out[i][j];
		}


		//根据电路输入in[][],计算理论输出
		for (int time = 0; time < b; time++) //b次实验
		{
			//先计算所有门的输出
			counts.resize(0);
			for (int i = 0; i < g; i++)
				dfs(in[time], i);
			for (int i = 0; i < u; i++)
				out_ture[time][i] = Gate[index.at(i) - 1].out;
			/*for (int j = 0; j < u; j++)
				cout << Gate[index.at(j) - 1].out << " ";
			cout << endl;*/
		}

		//理论输出计算完毕,和实际输出进行对比
		vector<string> fault(0); //错误信息容器
		cout << "Case " << turn << ": ";
		//依次检测每个门
		for (int i = 0; i < g; i++) {
			int sum0 = 0, sum1 = 0, sum2 = 0;//0,1 ,反的计数器
			for (int j = 0; j < b; j++)
			{
				if (out[j][i] != out_ture[j][i])
					sum2++;
				if (out[j][i] == 0)
					sum0++;
				if (out[j][i] == 1)
					sum1++;
			}
			if (sum2 == b) //每次都相反
			{
				fault.resize(fault.size() + 1);
				fault[fault.size() - 1] = "Gate " + to_string(index.at(i)) + " is failing; output inverted";
			}
			if (sum2 > 0 && sum0 == b) //每次都为0且有错
			{
				fault.resize(fault.size() + 1);
				fault[fault.size() - 1] = "Gate " + to_string(index.at(i)) + " is failing; output stuck at 0";
			}
			if (sum2 > 0 && sum1 == b)//每次都为1且有错
			{
				fault.resize(fault.size() + 1);
				fault[fault.size() - 1] = "Gate " + to_string(index.at(i)) + " is failing; output stuck at 1";
			}
		}
	
		//没有错误信息
		if (fault.size() == 0)
			cout << "No faults detected" << endl;
		//一个错误信息
		else if (fault.size() == 1)
			cout << fault[0] << endl;
		//多个错误信息
		else cout << "Unable to totally classify the failure" << endl;
		turn++;
	}

	return 0;
}

运行结果:
在这里插入图片描述
代码版本是C++11,官网无法运行,需要自己写一个to_string,以及不能直接用集合做参数。还有一点就是,官网给的答案有些是错的,不信可自行验证。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NLP饶了我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值