📅  最后修改于: 2023-12-03 15:28:37.904000             🧑  作者: Mango
本题是计算机科学与工程领域的GATE CS 2018试题中第52题。该题的难度为中等。
有一个大小为 N
的正方形矩阵,其中每个元素可以为 0
或 1
。你需要将其中一些元素修改为 1
,使得任意一个大小为 3*3
的子矩阵中,恰好有一个元素为 1
。你的任务是计算最小需要修改的元素数量。
第一行输入一个整数 T
,表示测试数据组数。对于每组数据,第一行输入一个正整数 N
,表示正方形矩阵的大小。接下来 N
行,每行输入 N
个整数,表示矩阵中相应位置元素的值。
对于每组数据,输出一行一个整数,表示最小需要修改的元素数量。
输入:
2
3
1 0 0
0 0 0
0 0 0
4
1 0 0 0
0 0 0 0
0 0 1 0
0 0 0 0
输出:
1
2
该题是一道矩阵题目,需要我们求解最小的修改数。其实我们可以发现,在一个合法的矩阵中,中心一定有且仅有一个 1
。
因此,我们需要对所有可能的中心位置枚举,统计所需要修改的元素数,最终取所有中心位置修改元素数的最小值作为答案即可。
还需要注意的是,对于边缘和角落位置,需要特别考虑,因为这些位置只有部分能够构成 $3*3$ 的矩阵,因此它们的结果需要特别的处理。
详见代码注释。
def min_modifications(matrix):
n = len(matrix)
m = n + 2 # 为了方便处理边界和角落的情况,增加了额外的一圈
# 生成额外的一圈,并将原矩阵赋值到中间部分
extra_matrix = [[0] * m for _ in range(m)]
for i in range(1, m - 1):
for j in range(1, m - 1):
extra_matrix[i][j] = matrix[i - 1][j - 1]
min_count = float('inf') # 记录最小修改元素数
# 枚举中心位置,计算需要修改的元素数
for i in range(1, m - 1):
for j in range(1, m - 1):
count = 0 # 记录修改元素数
for x in range(-1, 2): # 遍历 $3*3$ 中的所有位置
for y in range(-1, 2):
if extra_matrix[i + x][j + y] == 1:
if x == 0 and y == 0: # 中心位置必须是 $0$
count = float('inf')
break
else:
if abs(x) <= 1 and abs(y) <= 1: # 靠近中心的位置必须是 $1$
count += 1
if count == float('inf'):
break
min_count = min(min_count, count)
return min_count
if __name__ == "__main__":
test_cnt = int(input().strip())
for t in range(test_cnt):
n = int(input().strip())
matrix = []
for i in range(n):
line = input().strip().split()
matrix.append([int(c) for c in line])
count = min_modifications(matrix)
print(count)
输出的markdown格式:
# 门| GATE CS 2018 | 第 52 题
## 题目描述
有一个大小为 `N` 的正方形矩阵,其中每个元素可以为 `0` 或 `1`。你需要将其中一些元素修改为 `1`,使得任意一个大小为 `3*3` 的子矩阵中,恰好有一个元素为 `1`。你的任务是计算最小需要修改的元素数量。
## 输入格式
第一行输入一个整数 `T`,表示测试数据组数。对于每组数据,第一行输入一个正整数 `N`,表示正方形矩阵的大小。接下来 `N` 行,每行输入 `N` 个整数,表示矩阵中相应位置元素的值。
## 输出格式
对于每组数据,输出一行一个整数,表示最小需要修改的元素数量。
## 示例
输入:
2 3 1 0 0 0 0 0 0 0 0 4 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
输出:
1 2
## 解题思路
该题是一道矩阵题目,需要我们求解最小的修改数。其实我们可以发现,在一个合法的矩阵中,中心一定有且仅有一个 `1`。
因此,我们需要对所有可能的中心位置枚举,统计所需要修改的元素数,最终取所有中心位置修改元素数的最小值作为答案即可。
还需要注意的是,对于边缘和角落位置,需要特别考虑,因为这些位置只有部分能够构成 $3*3$ 的矩阵,因此它们的结果需要特别的处理。
详见代码注释。
## 代码实现
```python
def min_modifications(matrix):
n = len(matrix)
m = n + 2 # 为了方便处理边界和角落的情况,增加了额外的一圈
# 生成额外的一圈,并将原矩阵赋值到中间部分
extra_matrix = [[0] * m for _ in range(m)]
for i in range(1, m - 1):
for j in range(1, m - 1):
extra_matrix[i][j] = matrix[i - 1][j - 1]
min_count = float('inf') # 记录最小修改元素数
# 枚举中心位置,计算需要修改的元素数
for i in range(1, m - 1):
for j in range(1, m - 1):
count = 0 # 记录修改元素数
for x in range(-1, 2): # 遍历 $3*3$ 中的所有位置
for y in range(-1, 2):
if extra_matrix[i + x][j + y] == 1:
if x == 0 and y == 0: # 中心位置必须是 $0$
count = float('inf')
break
else:
if abs(x) <= 1 and abs(y) <= 1: # 靠近中心的位置必须是 $1$
count += 1
if count == float('inf'):
break
min_count = min(min_count, count)
return min_count
if __name__ == "__main__":
test_cnt = int(input().strip())
for t in range(test_cnt):
n = int(input().strip())
matrix = []
for i in range(n):
line = input().strip().split()
matrix.append([int(c) for c in line])
count = min_modifications(matrix)
print(count)
算法的时间复杂度为 $O(T*N^2)$,其中 $T$ 表示测试数据组数, $N$ 表示矩阵的大小。