📅  最后修改于: 2023-12-03 14:58:37.649000             🧑  作者: Mango
本题是一个电路模拟问题,你需要实现一个简易的电路模拟器,支持门电路的构建和计算。
题目给定一个电路结构以及各个门的类型和输入输出关系,需要计算电路的输出。电路由多个门和导线组成,每个门可以有多个输入和一个输出,每个导线连接两个门或一个门和一个输入节点或输出节点。题目中规定输入节点的编号为负数,输出节点的编号为正数。
在计算电路输出的过程中,需要遍历电路中所有的门并计算它们的输出。具体计算方式如下:
对于某些电路,可能存在循环依赖关系。例如,两个门 A 和 B 互相输入,这种情况下需要处理成同时计算两个门的输出,直至收敛。
输入包含若干行,每行代表一个门或者导线的描述。
门的描述格式为:
gate_id gate_type input_1 input_2 ... input_n
gate_id :门的编号,为一个整数;
gate_type :门的类型,为以下值之一:
input_1 到 input_n :门的输入,为负整数或前面已定义的门的编号。
导线的描述格式为:
0 input_gate_id output_gate_id
输出包含一个整数,代表整个电路的输出值。
1 3 -2
2 3 -3
3 2 1 2
4 3 -1 3
5 3 3 4
0 5 1
1
上述电路可以用如下图示表示:
1
↓
3 - 5 -|→4
↓
2
1 3 -2
2 3 3
3 0 1 4
4 3 -1 3
0 2 5
5 1 -3
0
上述电路可以用如下图示表示:
5
↓
2 - 3 - 4 -|→输出
↗ ↑
1 -|-↓
↓
-3
class Wire:
def __init__(self, gate):
self.gate = gate
self.value = None
class Gate:
def __init__(self, gtype, inputs, outputs):
self.gtype = gtype
self.inputs = inputs
self.outputs = outputs
self.value = None
self.wires_in = [Wire(self) for _ in range(len(inputs))]
self.wires_out = [Wire(self) for _ in range(len(outputs))]
# Set value if all inputs are available
def calculate(self):
if None in [w.value for w in self.wires_in]:
return
if self.gtype == 0:
self.value = all(w.value for w in self.wires_in)
elif self.gtype == 1:
self.value = any(w.value for w in self.wires_in)
elif self.gtype == 2:
self.value = sum(w.value for w in self.wires_in) == 1
elif self.gtype == 3:
self.value = not self.wires_in[0].value
# Propagate value to output wires and gates
def propagate(self):
for wire in self.wires_out:
if wire.gate in processed_gates:
continue # Stop recursion if gate has already been processed
wire.value = self.value
processed_wires.append(wire)
wire.gate.calculate()
processed_gates.append(wire.gate)
wire.gate.propagate()
inputs = {}
outputs = {}
wires = {}
gates = []
# Parse input
for i in range(int(input())):
words = input().split()
gate_id = int(words[0])
inputs[gate_id] = True
gate_type = int(words[1])
inputs_gates = [int(w) for w in words[2:]]
outputs_gates = [inputs_gates.pop()]
for input_gate_id in inputs_gates:
if input_gate_id not in wires:
wires[input_gate_id] = []
wires[input_gate_id].append(gate_id)
for output_gate_id in outputs_gates:
if output_gate_id not in wires:
wires[output_gate_id] = []
wires[gate_id] = [output_gate_id]
if output_gate_id in inputs:
outputs[gate_id] = True
gates.append(Gate(gate_type, inputs_gates, outputs_gates))
# Calculate output(s)
processed_wires = []
processed_gates = []
for input_gate_id in inputs:
if input_gate_id not in wires:
continue
for output_gate_id in wires[input_gate_id]:
if output_gate_id in inputs:
continue
outputs[output_gate_id] = True
wires[input_gate_id].remove(output_gate_id)
gates.append(Gate(None, [input_gate_id], [output_gate_id]))
for gate in gates:
gate.calculate()
processed_gates.append(gate)
for wire in gate.wires_out:
wire.value = gate.value
processed_wires.append(wire)
while True:
new_wires = []
for wire in processed_wires:
for connected_gate in wires.get(wire.gate.outputs[0], []):
new_wire = Wire(connected_gate)
new_wire.value = wire.value
processed_gates.append(connected_gate)
connected_gate.wires_in[connected_gate.inputs.index(wire.gate.outputs[0])] = new_wire
new_wires.append(new_wire)
if not new_wires:
break
processed_wires = new_wires
processed_wires = []
processed_gates = []
for gate in gates:
if gate.gtype is None:
continue # Skip input-only gates
if gate in processed_gates:
continue # Skip reprocessing gates
processed_gates.append(gate)
gate.propagate()
print(int(any(gate.value for gate in gates if gate.gtype is None and gate.outputs[0] in outputs)))
代码简介:
类 Wire 代表一个导线,其属性 gate 表示连接到的门,value 表示当前导线上的值。类 Gate 代表一个门,其中 gtype、inputs 和 outputs 分别为门的类型、输入和对应的输出门节点或输出节点编号。Gate 实例的 wires_in 和 wires_out 为输入和输出导线组成的列表,其中每个元素为 Wire 实例。calculate() 和 propagate() 分别用于计算门的输出和将输出传递到下一级门。
程序从标准输入中读取输入数据,并尝试构建出电路结构。实现过程中,将所有输入门(编号为负数)和输出节点(编号为正数)记录到 inputs 和 outputs 字典中,依次读取每个门的描述,先处理导线,再处理输入和输出门,最后根据输入门的值计算电路的输出。在计算时,如果门的输入尚未全部就绪,将不进行计算,直至计算完全可行。为处理循环依赖,采用了递归向下传值的方式,在计算出所有正在使用中的门的输出后,对输出值已知的门向下传值,直至传递到输出节点或未连通的门。
最后输出输出节点的值或者逻辑或的结果即可。