📌  相关文章
📜  门| Sudo GATE 2020 Mock I(2019 年 12 月 27 日)|第 42 题(1)

📅  最后修改于: 2023-12-03 15:42:20.307000             🧑  作者: Mango

题目描述:

有一个由 n 个门组成的走廊,每个门要么是开着的,要么是关着的。同时你会发现,如果门 i 开着,那么当你从门 i 出去时,所有的编号比 i 大的门都会自动打开。例如,如果门 3 开着,你从门 3 出去,那么门 4、门 5... 以此类推都会自动打开。

你被关在了某个房间里,请计算至少需要开几扇门,你才能从这个房间走出去。你可以假设初始时房间门是打开的。

对于 n (1 <= n <= 10^9)m (1 <= m <= 10^5) 个查询,每个查询给出一个 i 表示我们要确定从房间 i 出去至少需要开几扇门。

示例:

输入:
4 3
1 2 3
2 1 4
3 1 1

输出:
2
3
1

解题思路:

一开始所有的门都是打开的,所以我们可以建一个数组 opened[] 表示第 i 扇门是否开着。然后我们对每个查询,从这个房间开始,按照题目描述模拟即可。

具体来说,我们可以用一个变量 ans 来维护当前至少需要开多少扇门。

具体模拟方法如下:

  1. 将当前房间的门状态改成关闭。
  2. 从当前房间开始向下搜索,在遇到打开的门之前,将一直保持当前门为关闭状态。
  3. 如果遇到了一个“开着”的门,我们就更新 ans 的值,并将当前房间改为这扇门可以打开的所有后继房间中最大的那个。
  4. 重复上述步骤 1 至 3,直到能够走出这个房间。
算法实现:
def min_doors(n, m, queries):
    opened = [True] * (n + 1)
    ans = 1
    
    for i in range(m):
        room = queries[i][0]
        doors = queries[i][1:]
        
        cnt = 0
        while room <= n and not opened[room]:
            cnt += 1
            room += 1
        
        if room > n:
            opened[n] = True
            ans += cnt
        else:
            for door in doors:
                if door > room:
                    opened[door] = True
            ans += 1
        
    return ans
复杂度分析:

该算法的时间复杂度为 $O(m(n+1))$,其中 $m$ 表示查询的数量,$n$ 表示门的数量。该算法对于 $n$ 很大的情况下,是无法接受的,但是对于本题中给出的 $n$ 的范围,完全可以承受。空间复杂度同样为 $O(n)$。