📌  相关文章
📜  门| Sudo GATE 2020 Mock II(2019 年 1 月 10 日)|第 61 题(1)

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

题目介绍

本题为 Sudo GATE 2020 Mock II(2019 年 1 月 10 日)的第 61 题,题目名称为"门"。

题目描述如下:

有一个包含 $N$ 个门的房间,在 $p_1, p_2, \ldots, p_{N-1}$ 的位置上有 $N-1$ 个人。如果一个人在位置 $p$ 上,他将能够看到位置 $[1, p-1]$ 及 $[p+1, N]$ 上的人(即他不能看到与他同位置的其他人)。如果一个人想要离开某个房间,需要找到看不到他的人的数量。请你回答所有人离开房间所需的最小时间。

数据范围:

$1 \leq N \leq 10^5$ $1 \leq p_i \leq N$

解题思路

这道题是一道纯粹的模拟题目,通过模拟所有的操作来求解答案。

首先,在模拟之前,我们需要将 $p_i$ 进行升序排列。这样可以帮助我们方便地求出一个人可以看到的另一个人的位置。

首先,我们可以通过数组 $l$ 和 $r$ 来维护当前某一个人所能看到的另一个人的位置。具体来说,假设当前有 $k$ 个人,那么对于第 $i$ 个人,我们可以维护 $l_i$ 表示它能够看到的最左边的人的位置,$r_i$ 表示它能够看到的最右边的人的位置。

这两个数组的初始值为:$l_1=1, r_k=N$,对于其他的 $i$,我们可以通过以下的公式进行维护:

$$ l_i = \max(l_{i-1}, p_{i-1}+1) $$ $$ r_i = \min(r_{i-1}, p_i-1) $$

接下来,我们考虑如何求解一个人能够看到的人的数量。我们可以通过 $l$ 和 $r$ 数组来求解。具体来说,第 $i$ 个人看不到的人数就等于 $r_i-l_i+1$。

最后,我们计算所有人离开房间所需的最小时间。我们可以遍历一遍所有的人,在遍历的过程中记录下每个人能够看到的人的数量,然后取所有这些数量的最大值即可。最终的答案就是所有人能够看到的人数的最大值。

代码实现

下面是代码实现的示例,使用 Python 语言实现:

def min_time_to_leave(n: int, p: List[int]) -> int:
    p_sort = sorted(p)
    l = [1] + [0] * (n-1)
    r = [n] + [0] * (n-1)
    for i in range(1, n):
        l[i] = max(l[i-1], p_sort[i-1]+1)
        r[i] = min(r[i-1], p_sort[i]-1)
    max_v = -1
    for i in range(n):
        cnt = r[i]-l[i]+1
        if cnt > max_v:
            max_v = cnt
    return max_v

其中:

  • n 表示一共有多少个门;
  • p 是一个长度为 $n-1$ 的数组,表示在哪些位置上有人。