📅  最后修改于: 2023-12-03 14:58:37.745000             🧑  作者: Mango
这是一道机试题目,题目来源于门·门模拟 2017。本题目要求实现一个以命令行方式运行的模拟程序,通过输入不同的指令模拟门的开关,控制检测器的输出。
题目链接:门|门模拟 2017 |第 59 题
输入格式:
第一行包含两个整数n和m,表示门和传感器的数量。
接下来m行,每行描述一个传感器。每行包含三个整数t, a, b。
其中t表示传感器类型:1表示开门传感器,2表示关门传感器,3表示普通传感器;a和b表示传感器所在的门编号。如果t为3,那么a和b表示传感器在门上的编号。
接下来一行一个整数q,表示指令个数。
接下来q行,每行描述一个指令。每行包含一个整数o和两个门的编号a和b。
如果o为1,表示将门a和门b连接(可以理解为门a中的一个开关与门b中的一个开关相连)。
如果o为2,表示将门a和门b并联(可以理解为门a和门b中的开关都需要同时连接)。
输出格式:
根据题目要求,我们需要利用输入的指令模拟开门、关门或检测门的状态。具体实现可以使用数据结构中的图或树进行模拟,控制门之间的连接关系。当传感器检测到门的状态改变时,即输出传感器编号。
class Door:
def __init__(self):
self.open = False
self.sensors = []
class Sensor:
def __init__(self, t, a, b, sensor_id):
self.t = t
self.a = a
self.b = b
self.sensor_id = sensor_id
def dfs(u, door_list, sensor_list, visited):
visited[u] = 1
for v in door_list[u].sensors:
if visited[v.sensor_id] == 0:
if v.t == 1:
if not door_list[v.a].open:
print(v.sensor_id,end=' ')
elif v.t == 2:
if door_list[v.a].open:
print(v.sensor_id,end=' ')
elif v.t == 3:
if door_list[v.a].open and not door_list[v.b].open:
print(v.sensor_id, end=' ')
dfs(v.sensor_id, door_list, sensor_list, visited)
def main():
n, m = map(int, input().split())
door_list = [Door() for i in range(n+1)]
sensor_list = []
for i in range(1, m+1):
t, a, b = map(int, input().split())
if t != 3:
sensor = Sensor(t, a, b, i)
door_list[a].sensors.append(sensor)
door_list[b].sensors.append(sensor)
sensor_list.append(sensor)
else:
door_list[a].sensors.append(Sensor(t, a, b, 0))
q = int(input())
for i in range(q):
o, a, b = map(int, input().split())
if o == 1:
door_list[a].sensors.extend(door_list[b].sensors)
else:
for sensor in door_list[b].sensors:
door_list[a].sensors.append(sensor)
sensor.a = a
for door in door_list:
door.open = False
dfs(1, door_list, sensor_list, [0] * (m+1))
if __name__ == '__main__':
main()
在本题中,我们首先定义了两个类Door
和Sensor
,分别表示门和传感器。Door
类只需要存储门当前的状态和连接的传感器即可;而Sensor
类则需要存储传感器类型、所连接的门以及传感器的编号。在输入过程中,我们利用列表存储所有的门和传感器,以便在后续的操作中使用。
在读取完输入后,我们需要根据连接关系建立门和传感器之间的关系。我们可以使用邻接表来存储门和传感器之间的连接关系,这样可以减小空间复杂度。对于每个传感器,我们需要将它连接的两个门,以及传感器编号存储在两个门的邻接表中。
接下来,我们需要根据输入的指令模拟门的连接关系,以及门开关状态的变化。对于第一种指令,我们只需要将两个门的邻接表合并即可;对于第二种指令,则需要将要并联的门的邻接表合并到目标门邻接表中,同时修改传感器连接的门的编号。
最后,我们需要模拟门的开关状态,检测传感器是否触发。这里我们使用深度优先搜索,遍历当前门连接的所有传感器,检测传感器是否触发,以及触发时输出传感器编号。在每次遍历之前,需要将标记数组重置。