【华为OD机试真题E卷】521、 机器人可活动的最大网格点数目 | 机试真题+思路参考+代码解析(E卷复用)(C++)

一、题目

参考链接:https://sars2025.blog.csdn.net/article/details/141748083

题目描述

现有一个机器人口,可放置于MxN的网格中任意位置,每个网格包含一个整数编号,当相邻网格的数字编号差值的绝对值小于等
于1时,机器人可以在网格间移动。
问题:求机器人可活动的最大范围对应的网格点数目
说明:网格左上角坐标为(0,0),右下角坐标为(m-1,n-1),机器人只能在相邻网格间上下左右移动

输入输出

输入
第1行输入为M和N,M示网格的行数N表示网格的列数
之后M行表示网格数值,每行N个数值(数值大小用k示)
数值间用单个空格分隔,行首行尾无多余空格。
M、N、k均为整数,且1≤M,N≤150,0≤k≤50
输出
输出1行,包含1个数字,表示最大活动区域的网格点数目,行首行尾无多余空格

样例1

输入
4 4
1 2 5 2
2 4 4 5
3 5 7 1
4 6 2 4

输出
6

一、代码与思路

🧠C++语言思路

1.首先定义一个深度优先搜索函数dfs,用于计算从指定位置出发的活动区域的网格点数目
2.在dfs函数中,首先获取网格的行数m和列数n,并初始化活动区域的网格点数目为1。然后标记当前网格为已访问状态,
3.定义一个存储上下左右四个方向偏移量的directions数组。
4.遍历directions数组中的每个方向,计算新的坐标nx和ny。
5.如果新坐标满足条件(在网格范围内、未被访问、相邻网格编号差值的绝对值小于等于1),则递归调用dfs函数计算新位置的活动区
域的网格点数目,并将其累加到area中。
6.最后返回area作为当前位置的活动区域的网格点数目。
7.定义主函数main,在main函数中首先读取输入的网格大小m和n,并创建一个二维vector grid用于存储网格。
8.通过嵌套循环读取每个网格的数值,并将其存储在grid中。
9.调用maxGridArea函数计算最大活动区域的网格点数目,并将结果输出到标准输出流中。
10.返回0,表示程序执行完毕。

✅C++代码

#include <iostream>
#include <vector>
using namespace std;

int dfs(vector<vector<int>>& grid, int i, int j, vector<vector<bool>>& visited) {
    int m = grid.size();
    int n = grid[0].size();
    int area = 1;  // 活动区域的网格点数目,初始为1
    visited[i][j] = true;  // 将当前网格标记为已访问

    vector<pair<int, int>> directions = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};  // 上下左右四个方向的偏移量

    // 深度优先搜索
    for (auto direction : directions) {
        int dx = direction.first;
        int dy = direction.second;
        int nx = i + dx;
        int ny = j + dy;

        if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny] && abs(grid[nx][ny] - grid[i][j]) <= 1) {
            // 如果相邻网格满足条件(编号差值的绝对值小于等于1),则继续搜索
            area += dfs(grid, nx, ny, visited);
        }
    }

    return area;
}

int maxGridArea(vector<vector<int>>& grid) {
    int m = grid.size();  // 网格的行数
    int n = grid[0].size();  // 网格的列数

    int maxArea = 0;  // 最大活动区域的网格点数目

    // 创建一个与网格大小相同的二维数组,用于记录已访问的网格
    vector<vector<bool>> visited(m, vector<bool>(n, false));

    // 遍历网格的每个位置作为起点
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (!visited[i][j]) {
                int area = dfs(grid, i, j, visited);  // 深度优先搜索计算当前起点的活动区域的网格点数目
                maxArea = max(maxArea, area);  // 更新最大活动区域的网格点数目
            }
        }
    }

    return maxArea;
}

int main() {
    int m, n;
    cin >> m >> n;

    vector<vector<int>> grid(m, vector<int>(n));

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            cin >> grid[i][j];
        }
    }

    int maxArea = maxGridArea(grid);

    cout << maxArea << endl;

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值