📜  门| GATE CS Mock 2018 |第 58 题(1)

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

门| GATE CS Mock 2018 | 第 58 题

题目描述:有一个开关和 n 个门,你可以通过开关控制每扇门的状态。开始时,所有门都是关闭的。然后有 q 个操作,每个操作是以下两个操作之一:

  1. Toggle (i, j):这个操作会将从第 i 扇门到第 j 扇门(除了当前状态为锁定的门)之间的所有门的状态从关闭变成打开,从打开变成关闭。

  2. Lock (i, j):这个操作会将从第 i 扇门到第 j 扇门之间的所有门的状态锁定,以防止任何进一步的 Toggle 操作影响这些门。

现在,请你编写一个程序,计算在执行所有这样的操作之后,有多少扇门处于打开状态。

本问题的输入输出格式如下:

输入格式:

  • 第一行包含两个空格分隔的整数 n 和 q,表示门和操作的数量。
  • 接下来 q 行,每行包含一个表示操作的整数和两个表示门编号的空格分隔的整数。

输出格式:

  • 一个整数,表示所有操作执行完成后,有多少个门是打开状态。

解题思路:对于一个门,初始状态为关闭。使用一个数组 gates来记录每扇门的状态,gates[i] 的值为 0 时表示当前门关闭,为 1 时表示当前门打开,为 -1 时表示当前门被锁定。对于每个操作,根据操作类型分别处理。

  1. Toggle (i, j):对于 i 到 j 之间的每扇门,将状态取反,但要判断当前门是否被锁定。

  2. Lock (i, j):对于 i 到 j 之间的每扇门,将状态设置为 -1。

最后,遍历每扇门的状态,统计打开的门的数量。

时间复杂度:O(qn)

空间复杂度:O(n)

代码如下(Python实现):

n, q = map(int, input().split())
gates = [0] * (n + 1)

for _ in range(q):
    op, i, j = map(int, input().split())
    if op == 1:
        for k in range(i, j + 1):
            if gates[k] != -1:  # 未被锁定
                gates[k] ^= 1  # 取反操作
    else:
        for k in range(i, j + 1):
            gates[k] = -1  # 锁定

count = 0
for i in range(1, n + 1):
    if gates[i] == 1:
        count += 1

print(count)

注:该题还有一个数据结构(如线段树、树状数组)的解法,具体可参见其他资料。