📜  门|门模拟 2017 |第 59 题(1)

📅  最后修改于: 2023-12-03 14:58:37.745000             🧑  作者: Mango

门|门模拟 2017 |第 59 题

简介

这是一道机试题目,题目来源于门·门模拟 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中的开关都需要同时连接)。

输出格式:

  • 一行一个字符串。每当一个传感器输出1时,输出该传感器编号后面跟一个空格。
思路分析

根据题目要求,我们需要利用输入的指令模拟开门、关门或检测门的状态。具体实现可以使用数据结构中的图或树进行模拟,控制门之间的连接关系。当传感器检测到门的状态改变时,即输出传感器编号。

代码实现
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()

在本题中,我们首先定义了两个类DoorSensor,分别表示门和传感器。Door类只需要存储门当前的状态和连接的传感器即可;而Sensor类则需要存储传感器类型、所连接的门以及传感器的编号。在输入过程中,我们利用列表存储所有的门和传感器,以便在后续的操作中使用。

在读取完输入后,我们需要根据连接关系建立门和传感器之间的关系。我们可以使用邻接表来存储门和传感器之间的连接关系,这样可以减小空间复杂度。对于每个传感器,我们需要将它连接的两个门,以及传感器编号存储在两个门的邻接表中。

接下来,我们需要根据输入的指令模拟门的连接关系,以及门开关状态的变化。对于第一种指令,我们只需要将两个门的邻接表合并即可;对于第二种指令,则需要将要并联的门的邻接表合并到目标门邻接表中,同时修改传感器连接的门的编号。

最后,我们需要模拟门的开关状态,检测传感器是否触发。这里我们使用深度优先搜索,遍历当前门连接的所有传感器,检测传感器是否触发,以及触发时输出传感器编号。在每次遍历之前,需要将标记数组重置。