华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
有兴趣的同学可以扫码添加我们的VX:code5bug。
题目描述
存在一个 m*n 的二维数组,其成员取值范围为0或1。其中值为1的成员具备扩散性,每经过1S,将上下左右值为0的成员同化为1,二维数组的成员初始值都为0,将第 [i, j] 和[k,l]两个位置上元素修改成1后,求矩阵的所有元素变为1需要多长时间。
输入描述
输出数据中的前2个数字表示这是一个m*n的矩阵,m和n不会超过1024大小;
中间两个数字表示一个初始扩散点位置为i,j;
最后2个数字表示另一个扩散点位置为K,l。
输出描述
输出矩阵的所有元素变为1所需要秒数。
示例1
输入:
4,4,0,0,3,3
输出:
3
说明:
输出数据中的前2个数字表示这是一个4*4的矩阵;中间两个数字表示一个初始扩散点位置为0,0;最后2个数字表示另一个扩散点位置为3,3.
给出的样例是一个很简单模型,初始点在对角线上,达到中间的位置分别为3次选代,即3秒,所以输出为3.
Python
[代码仅供学习参考并未进行大量数据测试]
from collections import deque
# 读取输入
m, n, i, j, k, l = map(int, input().split(","))
# 初始化 m*n 矩阵,全部设为 0
g = [[0] * n for _ in range(m)]
# 队列用于 BFS
q = deque()
# 两个个扩散点
q.extend([(i, j), (k, l)])
g[i][j] = g[k][l] = 1
second = 0 # 记录扩散所需秒数
# 方向数组:用于表示上下左右四个方向的偏移量
dirs = [-1, 0, 1, 0, -1]
# 执行 BFS 扩散
while q:
size = len(q) # 当前扩散层的大小
for _ in range(size):
# 处理当前层的所有节点
curX, curY = q.popleft()
# 遍历上下左右四个方向
for j in range(1, 5):
r = curX + dirs[j - 1]
c = curY + dirs[j]
# 判断是否越界,或者已经被扩散
if r < 0 or c < 0 or r == m or c == n or g[r][c] == 1:
continue
q.append((r, c)) # 将新的扩散点加入队列
g[r][c] = 1 # 标记当前点已扩散
if q:
second += 1 # 若队列仍然有元素,说明仍在扩散,时间 +1
# 输出所需时间
print(second)
题目类型
该题属于 BFS(广度优先搜索) 经典题型,类似于“多源BFS求最短路径”问题。BFS适用于求解 最短步数、最少操作次数 等问题。
解题思路
构建二维矩阵:
- 读取输入,创建一个大小为
m * n
的二维数组g
,初始时所有元素均为0
,表示未被感染。初始化BFS队列:
- 题目给出了两个初始扩散点
(i, j)
和(k, l)
,将它们入队并标记为1
(已感染),表示已经开始扩散。执行BFS扩散:
采用队列进行广度优先遍历,每次从队列中取出一个点
(x, y)
,检查其上下左右四个方向的相邻点:
- 若相邻点为
0
(未感染),则将其加入队列,并标记为1
(已感染)。这一轮扩散完成后,时间增加
1
秒。终止条件:
- 若所有点都被感染,则输出所需秒数。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏