📅  最后修改于: 2023-12-03 15:28:47.132000             🧑  作者: Mango
本题为Sudo GATE 2020 Mock I的第56题,题目名称为"门"。此题的难度为中等。
题目描述:在一个大小为$n$的环上有$m$个门和$k$个医生,每个门都位于环上,每个医生可以随意的在环上移动。当一个医生经过一个门时,如果他是第一次经过此门,则门会打开;如果他不是第一次经过此门,则门会关闭。现在医生们需要根据一定的路线轮流经过门,问最后哪些门会开启。
输入格式:第一行包含三个整数$n,m,k$;第二行包含$m$个整数,表示每个门所处的位置;第三行包含$k$个整数,表示每个医生所处的位置。
下面是本题的程序实现:
def find_open_doors(n,m,k,doors,doctors):
"""
在一个大小为n的环上有m个门和k个医生,每个门都位于环上,每个医生
可以随意的在环上移动。当一个医生经过一个门时,如果他是第一次经过此
门,则门会打开;如果他不是第一次经过此门,则门会关闭。现在医生们需
要根据一定的路线轮流经过门,问最后哪些门会开启。
:param n: 一个大小为n的环
:param m: m个门
:param k: k个医生
:param doors: 每个门所处的位置
:param doctors: 每个医生所处的位置
:return: 最后哪些门会开启
"""
count = [0] * m # 统计每个门被经过的次数
open = [] # 最终开启的门
for i in range(k):
for j in range(m):
if doctors[i] == doors[j]:
count[j] += 1
if count[j] == 1:
open.append(j+1)
break
open.sort()
return open
程序中的find_open_doors
函数接收5个参数:$n$、$m$、$k$、$doors$、$doctors$。函数首先创建一个长度为$m$的列表$count$,用来统计每个门被经过的次数;并创建一个空列表$open$,用来存放最终开启的门。然后对于每个医生,遍历每个门,如果医生和门的位置相同,则将此门被经过的次数加1,并判断此门是否被开启,如果是第一次被开启,则将门的编号加入$open$列表中。最后将$open$列表排序并返回。
该程序中,时间复杂度主要由两个循环决定,即$O(km)$。空间复杂度为$O(m)$。