(1)题目描述
(2)算法思想
本题难度其实不大,关键是耐心读题。
首先剖析一下题目的输入顺序以及格式:
1 //要解决的问题数目,本题由多个独立的子问题构成
3 5 //独立问题的电路输入个数以及器件个数
XOR 2 I1 I2 //器件类型、输入个数、每个输入端的编号,I开头表示直接输入,O开头表示器件输入
XOR 2 O1 I3
AND 2 O1 I3
AND 2 I1 I2
OR 2 O3 O4
4 //输入的次数,也即输出的次数
0 1 1 //每次输入时输入信号的状态
1 0 1
1 1 1
0 0 0
2 5 2 //每次输出的器件数量以及对应的器件编号
2 5 2
2 5 2
2 5 2
而输出的要求相对简单,根据独立子问题输入的最后一部分进行相应输出即可。
了解输入输出的格式后便可以开始实现了,思路如下:
- 首先接收输入,输入分为多个层次,最高一层为独立子问题的个数,第二层为每个子问题的相应输入,子问题中含有输入变量数量的还需要再分一层。
- 接收输入完毕后开始构建电路,我的思路是分层级,输入端为0级,直接接收输入端的为1级,输入端为器件输出端的层级为输入器件的层级+1并且取最大层级,这样进行一层一层的构建即可模拟整个逻辑电路的状态。
- 成环判断,这部分我看有人说可以使用拓扑排序,但是本人是个菜鸡算法什么的掌握粗浅,比赛时是使用一种类似判断刷新的方式进行判断的;具体就是记录前一状态每个器件的层级构建完毕状态,等这一轮构建完毕后进行比对,如果完全没有变化即可判断构成环,能用这种方式实现判断也是因为严格的层级构建方式,每一次必然至少会有一个器件得到自己的层级情况,如果使用其他方式进行构建这种方式便不一定适用了。
- 电路构建完毕后就可以接受输入端并进行输出了,在接受输入端信号之前需要先按照层级有小到大的顺序进行一次排序,保证每一层输入输出的有序;之后每个层级接受相应输入并进行计算,最后对应编号的器件进行信号输出即可。
不过这里有个比较坑的地方需要注意一下,样例中给的输入端编号的数字部分全部都是个位数,但是测试样例实际上是含有多位数的,在处理字符串时要小心不要只取数字部分的第一个字符导致错误(我会说我因为这个BUG改了一个半小时吗?好吧我承认我是个大傻逼QAQ)
(3)代码实现
#include<map>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
struct node {
int id;
int level;
int output;
string type;
bool iscreated;
vector<int> input;
vector<int> idvalid;
vector<string> inputid;
node () {
level=-1;
iscreated=0;
}
calculate() {
int ans=input[0];
if(type=="NOT")
ans=!input[0];
else if(type=="AND")
for(int i=1; i<input.size(); i++)
ans&=input[i];
else if(type=="OR")
for(int i=1; i<input.size(); i++)
ans|