【问题描述】
小蓝拥有 n × n 大小的棋盘,一开始棋盘上全都是白子。小蓝进行了m次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反(也就是白色棋子变为黑色,黑色棋子变为白色)。请输出所有操作做完后棋盘上每个棋子的颜色。
【输入格式】
输入的第一行包含两个整数n,m,用一个空格分隔,表示棋盘大小与操作数。
接下来m行每行包含四个整数 X1,Y1,X2,Y2,相邻整数之间使用一个空格分隔,表示将在X1至X2行和Y1至Y2列中的棋子颜色取反。
【输出格式】
输出n行,每行n个0或1表示该位置棋子的颜色。如果是白色则输出0,否则输出1。
【样例输入】
3 3
1 1 2 2
2 2 3 3
1 1 3 3
【样例输出】
001
010
100
python
def flip_chessboard(n, m, operations):
# 初始化一个(n+2) x (n+2)的二维数组pre,用于存储前缀和
# 多出的两行和两列是为了方便处理边界情况,避免在计算前缀和时越界
pre = [[0] * (n + 2) for _ in range(n + 2)]
# 处理每个操作,更新前缀和数组pre
for x1, y1, x2, y2 in operations:
# 在(x1, y1)位置增加1,表示开始翻转
pre[x1][y1] += 1
# 在(x1, y2+1)位置减去1,表示在y2之后不再翻转
pre[x1][y2 + 1] -= 1
# 在(x2+1, y1)位置减去1,表示在x2之后不再翻转
pre[x2 + 1][y1] -= 1
# 在(x2+1, y2+1)位置增加1,这是为了抵消之前的减法,确保其他区域不受影响
pre[x2 + 1][y2 + 1] += 1
# 初始化最终棋盘状态ans,并根据前缀和计算每个位置的实际翻转次数
ans = [[0] * n for _ in range(n)]
for i in range(1, n + 1):
for j in range(1, n + 1):
# 计算当前位置的前缀和
pre[i][j] += pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1]
# 根据前缀和的奇偶性确定棋子的颜色
ans[i - 1][j - 1] = 1 if pre[i][j] % 2 != 0 else 0
# 输出棋盘状态
for row in ans:
print(''.join(str(cell) for cell in row))
# 输入处理
if __name__ == "__main__":
# 从标准输入读取n和m
n, m = map(int, input().split())
# 读取所有操作,并存储在operations列表中
operations = [tuple(map(int, input().split())) for _ in range(m)]
# 调用函数翻转棋盘并输出结果
flip_chessboard(n, m, operations)