📜  门|门模拟 2017 |问题 28(1)

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

门|门模拟 2017 |问题 28

题目描述

有n个门,每个门有m个开关,第$i$个门上第$j$个开关控制它的状态,当且仅当其被人推开时,才能成功控制这扇门。在$t$次测试中,第$i$次测试需要操作第$x_i$扇门上的第$y_i$个开关,每次操作后,这扇门状态会发生变化,即原来开着的会关上,原来关着的会打开。每次操作后,输出现在哪些门是打开的。

输入格式

第$1$行有三个整数$n,m,t$,表示门的数量、每扇门上的开关数以及测试的次数。 接下来$t$行,每行两个整数$x_i,y_i$,表示进行第$i$次测试的门号和开关号。

输出格式

对于每个测试,输出一行,包含$n$个数,每个数为0或1,表示当前门的状态,相邻数字间用一个空格分隔。如果第$i$个门是打开的,则第$i$个数为1,否则为0。

样例

输入:

3 4 3
1 1
2 2
3 3

输出:

0 0 0
0 0 0
0 0 0
解题思路

首先,观察样例,发现每个门被推动的次数只有一次,如果有多次推动,应该使用状态矩阵来记录每个门的状态。状态矩阵是一个二维数组,记录每道门的开闭状态。当一个门被推动时,通过模拟操作来改变它的开闭状态。

我们可以开一个长度为$n$的数组$doors$来表示每扇门的状态,当$doors[i]=0$时,表示第$i$扇门是关着的,当$doors[i]=1$时,表示第$i$扇门是开着的。在输入测试序列后,遍历测试序列,每次操作时,对于第$x_i$扇门上的第$y_i$个开关,先将当前状态取反,然后重新记录到数组$doors$中。最终输出$doors$中的元素即可。

参考代码
# 门|门模拟 2017 |问题 28

n, m, t = map(int, input().split())

doors = [0] * n  # 初始化所有门的状态为关上

for i in range(t):
    x, y = map(int, input().split())
    doors[x - 1] ^= (1 << (y - 1))  # 对第x扇门上的第y个开关取反

for i in range(n):
    print(doors[i] >> (m - 1 - j) & 1, end=" ")  # 输出每扇门的状态
print()

代码说明:

  • 第1行,从输入中获取$n, m, t$。
  • 第3行,把所有门的状态初始化为0。
  • 第5-6行,遍历测试序列,对第$x$扇门的第$y$个开关进行操作。
  • 第7行,异或运算( ^ )实现取反。
  • 第9-11行,遍历所有门,输出每扇门的状态。