欢乐的周末 - 华为OD统一考试(JavaScript 题解)

alt

题目描述

小华和小为是很要好的朋友,他们约定周末一起吃饭。

通过手机交流,他们在地图上选择了多个聚餐地点(由于自然地形等原因,部分聚餐地点不可达)。

求小华和小为都能到达的聚餐地点有多少个?

输入描述

第一行输入m和n,m代表地图的长度,n代表地图的宽度

第二行开始具体输入地图信息,地图信息包含:

0 为通畅的道路

1 为障碍物 (且仅1为障碍物)

2 为小华或者小为,地图中必定有且仅有2个(非障碍物)

3 为被选中的聚餐地点 (非障碍物)

输出描述

可以被两方都到达的聚餐地点数量,行末无空格

示例1

输入:
4 4
2 1 0 3
0 1 2 1
0 3 0 0
0 0 0 0

输出:
2

说明:第一行输入地图的长宽为4,4,接下来4行是地图2表示华为的位置,3是聚餐地点,图中的两个3,小华和小为都可到达,所以输出2

示例2

输入
4 4
2 1 2 3
0 1 0 0
0 1 0 0
0 1 0 0

输出
0

JavaScript

const rl = require('readline').createInterface({
    input: process.stdin,
});
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

// Author: code5bug
void (async function () {
    // 读取m和n
    let firstLine = await readline();
    let [m, n] = firstLine.split(' ').map(Number);
    
    let g = []; // 网格
    let vis = []; // 访问标记数组
    
    // 初始化网格和访问数组
    for (let i = 0; i < m; i++) {
        let row = (await readline()).split(' ').map(Number);
        g.push(row);
        vis.push(new Array(n).fill(0));
    }
    
    // 查找起点位置(小华和小为的位置)
    let starts = [];
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            if (g[i][j] === 2) {
                starts.push([i, j]);
            }
        }
    }
    
    // DFS函数
    function dfs(g, r, c, vis, seq) {
        // 边界检查:越界、障碍物或已访问
        if (r < 0 || c < 0 || r >= m || c >= n || g[r][c] === 1 || ((vis[r][c] >> seq) & 1) === 1) {
            return;
        }
        
        // 标记当前位置已被第seq个人访问
        vis[r][c] |= (1 << seq);
        
        // 四个方向DFS
        dfs(g, r + 1, c, vis, seq);
        dfs(g, r - 1, c, vis, seq);
        dfs(g, r, c + 1, vis, seq);
        dfs(g, r, c - 1, vis, seq);
    }
    
    // 分别从两个起点进行DFS
    for (let i = 0; i < 2; i++) {
        let pos = starts[i];
        dfs(g, pos[0], pos[1], vis, i);
    }
    
    // 统计符合条件的聚餐地点
    let result = 0;
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            // 是聚餐地点且两个人都访问过
            if (g[i][j] === 3 && vis[i][j] === 3) {
                result++;
            }
        }
    }
    
    console.log(result);
    rl.close();
})();

题目描述
在一个m×n的网格中,0表示空地,1表示障碍物,2表示起点(有两个人),3表示聚餐地点。两个人分别从各自的起点出发,只能上下左右移动,不能穿过障碍物。求两人都能到达的聚餐地点的数量。

解题思路

  1. 使用深度优先搜索(DFS)分别从两个人的起点出发,标记所有可以到达的位置。
  2. 使用位运算来记录访问状态:vis数组的每个元素是一个整数,其二进制位表示不同人是否访问过该位置。
  3. 最后遍历所有聚餐地点,统计同时被两个人访问过的地点数量。

关键点

  • 使用位运算高效记录访问状态(第0位表示第一个人,第1位表示第二个人)
  • DFS遍历所有可达位置
  • 障碍物和边界条件的处理

复杂度分析

  • 时间复杂度:O(m×n),因为每个网格最多被访问两次(两个人各一次)
  • 空间复杂度:O(m×n),用于存储网格和访问状态

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

什码情况

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

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

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

打赏作者

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

抵扣说明:

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

余额充值