矩阵扩散 - 华为OD机试(A卷,JavaScript题解)

华为OD机试题库《C++》限时优惠 9.9

华为OD机试题库《Python》限时优惠 9.9

华为OD机试题库《JavaScript》限时优惠 9.9

针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。

有兴趣的同学可以扫码添加我们的微信(code5bug)了解一下。

华为OD机试

题目描述

存在一个 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适用于求解 最短步数最少操作次数 等问题。


解题思路

  1. 构建二维矩阵

    • 读取输入,创建一个大小为 m * n 的二维数组 g,初始时所有元素均为 0,表示未被感染。
  2. 初始化BFS队列

    • 题目给出了两个初始扩散点 (i, j)(k, l),将它们入队,表示已经开始扩散。
  3. 执行BFS扩散

    • 采用队列进行广度优先遍历,每次从队列中取出一个点 (x, y),检查其上下左右四个方向的相邻点:

      • 若相邻点为 0(未感染),则将其加入队列,并标记为 1(已感染)。
    • 这一轮扩散完成后,时间增加 1 秒。

  4. 终止条件

  • 若所有点都被感染,则输出所需秒数。

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

什码情况

你的鼓励就是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值