华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
有兴趣的同学可以扫码添加我们的微信(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.
JavaScript
[代码仅供学习参考并未进行大量数据测试]
const rl = require("readline").createInterface({
input: process.stdin,
});
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
const input = await readline();
const [m, n, i, j, k, l] = input.split(",").map(Number);
// 初始化 m*n 矩阵,全部设为 0
const g = Array.from({ length: m }, () => Array(n).fill(0));
// 队列用于 BFS
const q = [];
// 第一个扩散点
q.push([i, j]);
g[i][j] = 1;
// 第二个扩散点
q.push([k, l]);
g[k][l] = 1;
let second = 0; // 记录扩散所需秒数
// 方向数组:用于表示上下左右四个方向的偏移量
const dirs = [-1, 0, 1, 0, -1];
// 执行 BFS 扩散
while (q.length > 0) {
const size = q.length; // 当前扩散层的大小
for (let i = 0; i < size; i++) {
// 处理当前层的所有节点
const [curX, curY] = q.shift();
// 遍历上下左右四个方向
for (let j = 1; j < 5; j++) {
const r = curX + dirs[j - 1];
const c = curY + dirs[j];
// 判断是否越界,或者已经被扩散
if (r < 0 || c < 0 || r === m || c === n || g[r][c] === 1) {
continue;
}
q.push([r, c]); // 将新的扩散点加入队列
g[r][c] = 1; // 标记当前点已扩散
}
}
if (q.length > 0) {
second++; // 若队列仍然有元素,说明仍在扩散,时间 +1
}
}
// 输出所需时间
console.log(second);
rl.close();
})();
题目类型
该题属于 BFS(广度优先搜索) 经典题型,类似于“多源BFS求最短路径”问题。BFS适用于求解 最短步数、最少操作次数 等问题。
解题思路
构建二维矩阵:
- 读取输入,创建一个大小为
m * n
的二维数组g
,初始时所有元素均为0
,表示未被感染。初始化BFS队列:
- 题目给出了两个初始扩散点
(i, j)
和(k, l)
,将它们入队,表示已经开始扩散。执行BFS扩散:
采用队列进行广度优先遍历,每次从队列中取出一个点
(x, y)
,检查其上下左右四个方向的相邻点:
- 若相邻点为
0
(未感染),则将其加入队列,并标记为1
(已感染)。这一轮扩散完成后,时间增加
1
秒。终止条件:
- 若所有点都被感染,则输出所需秒数。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏