华为OD机试 - 可活动的最大网格点数目 - 广度优先搜索BFS(Python/JS/C/C++ 2024 E卷 200分)

news2024/10/5 10:41:51

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

现有一个机器人,可放置于 M × N 的网格中任意位置,每个网格包含一个非负整数编号,当相邻网格的数字编号差的绝对值小于等于 1 时,机器人可以在网格间移动。

问题:求机器人可活动的最大范围对应的网格点数量。
说明:网格左上角坐标为(0,0),右下角坐标为(M-1,N-1),机器人只能在相邻网格间上下左右移动。

二、输入描述

第 1 行输入 M 和 N,M 表示网格的行数 N 表示网格的列数
之后 M 行表示网格数组,每行 N 个数值(数值为 0 到 5 之间),数值间用单个空格分隔,行与行无多余空格。

M、N、K 均为整数,且 1 ≤ M, N ≤ 150, 0 ≤ K ≤ 50

三、输出描述

输出 1 行,包含 1 个数字,表示最大活动区域的网格点数目,行首行尾无多余空格。

四、测试用例

测试用例1:

1、输入

4 4
1 2 5 2
2 4 4 5
3 5 7 1
4 6 2 4

2、输出

6

3、说明

相邻网格差值的绝对值都小于等于 1,且为最大区域,对应网格点数目为 6。

测试用例2:

1、输入

3 3
0 1 0
1 2 1
0 1 0

2、输出

9

3、说明

所有网格点的编号差的绝对值都不超过 1,整个网格都是一个连通区域,包含 9 个网格点。

五、解题思路

1、问题理解

给定一个 M × N 的网格,网格中的每个点有一个非负整数编号(0 到 5)。机器人可以在网格中任意放置起始点,然后在相邻的上下左右网格间移动,移动的条件是相邻网格编号的差的绝对值不超过 1。要求求出机器人在网格中可活动的最大范围,即能够到达的网格点的最大数量。

2、解决方案

为了求解这个问题,我们需要找到网格中最大的连通区域,其中相邻网格之间的编号差的绝对值不超过 1。这个问题可以转化为在图中寻找最大连通分量的问题,其中每个网格点是图中的一个节点,相邻的节点之间有边连接,前提是它们的编号差的绝对值不超过 1。

遍历网格中的每一个未被访问的点,使用 BFS 来找到与之相连的所有符合条件的点,记录下连通区域的大小,并更新最大连通区域的大小。

六、Python算法源码

# Python版本
import sys
from collections import deque

def main():
    # 读取所有输入
    input = sys.stdin.read().split()
    idx = 0
    # 读取网格的行数M和列数N
    M = int(input[idx])
    N = int(input[idx + 1])
    idx += 2
    # 初始化网格数组
    grid = []
    for _ in range(M):
        row = []
        for _ in range(N):
            row.append(int(input[idx]))
            idx += 1
        grid.append(row)
    # 初始化访问标记数组,全部设置为False
    visited = [[False for _ in range(N)] for _ in range(M)]
    max_region = 0  # 记录最大连通区域的大小
    # 定义四个方向的移动:上、下、左、右
    directions = [(-1,0), (1,0), (0,-1), (0,1)]
    # 遍历每一个网格点
    for i in range(M):
        for j in range(N):
            if not visited[i][j]:
                # 使用BFS计算当前连通区域的大小
                queue = deque()
                queue.append((i,j))
                visited[i][j] = True
                count = 1
                while queue:
                    x, y = queue.popleft()
                    for dx, dy in directions:
                        new_x = x + dx
                        new_y = y + dy
                        # 判断新位置是否在网格范围内且未被访问
                        if 0 <= new_x < M and 0 <= new_y < N and not visited[new_x][new_y]:
                            # 判断编号差的绝对值是否小于等于1
                            if abs(grid[x][y] - grid[new_x][new_y]) <= 1:
                                queue.append((new_x, new_y))
                                visited[new_x][new_y] = True
                                count += 1
                # 更新最大连通区域的大小
                if count > max_region:
                    max_region = count
    # 输出结果
    print(max_region)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// JavaScript版本
const readline = require('readline');

// 创建接口以逐行读取输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let input = [];
rl.on('line', function(line){
    input = input.concat(line.trim().split(' '));
}).on('close', function(){
    let idx = 0;
    // 读取网格的行数M和列数N
    const M = parseInt(input[idx++]);
    const N = parseInt(input[idx++]);
    // 初始化网格数组
    let grid = [];
    for(let i = 0; i < M; i++){
        let row = [];
        for(let j = 0; j < N; j++){
            row.push(parseInt(input[idx++]));
        }
        grid.push(row);
    }
    // 初始化访问标记数组,全部设置为false
    let visited = Array.from({length: M}, () => Array(N).fill(false));
    let maxRegion = 0; // 记录最大连通区域的大小
    // 定义四个方向的移动:上、下、左、右
    const directions = [
        [-1, 0],
        [1, 0],
        [0, -1],
        [0, 1]
    ];
    // 遍历每一个网格点
    for(let i = 0; i < M; i++){
        for(let j = 0; j < N; j++){
            if(!visited[i][j]){
                // 使用BFS计算当前连通区域的大小
                let queue = [];
                queue.push([i, j]);
                visited[i][j] = true;
                let count = 1;
                while(queue.length > 0){
                    let [x, y] = queue.shift();
                    for(let dir = 0; dir < directions.length; dir++){
                        let newX = x + directions[dir][0];
                        let newY = y + directions[dir][1];
                        // 判断新位置是否在网格范围内且未被访问
                        if(newX >=0 && newX < M && newY >=0 && newY < N && !visited[newX][newY]){
                            // 判断编号差的绝对值是否小于等于1
                            if(Math.abs(grid[x][y] - grid[newX][newY]) <= 1){
                                queue.push([newX, newY]);
                                visited[newX][newY] = true;
                                count++;
                            }
                        }
                    }
                }
                // 更新最大连通区域的大小
                if(count > maxRegion){
                    maxRegion = count;
                }
            }
        }
    }
    // 输出结果
    console.log(maxRegion);
});

八、C算法源码

/* C语言版本 */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// 定义队列结构
typedef struct {
    int x;
    int y;
} Point;

// 定义队列大小
typedef struct {
    Point *data;
    int front;
    int rear;
    int size;
} Queue;

// 初始化队列
Queue* createQueue(int max_size){
    Queue *q = (Queue*)malloc(sizeof(Queue));
    q->data = (Point*)malloc(sizeof(Point)*max_size);
    q->front = 0;
    q->rear = 0;
    q->size = max_size;
    return q;
}

// 判断队列是否为空
bool isEmpty(Queue *q){
    return q->front == q->rear;
}

// 入队
void enqueue(Queue *q, int x, int y){
    q->data[q->rear].x = x;
    q->data[q->rear].y = y;
    q->rear = (q->rear + 1) % q->size;
}

// 出队
Point dequeue(Queue *q){
    Point p = q->data[q->front];
    q->front = (q->front + 1) % q->size;
    return p;
}

int main(){
    int M, N;
    // 读取网格的行数M和列数N
    scanf("%d %d", &M, &N);
    // 动态分配网格数组
    int **grid = (int**)malloc(sizeof(int*)*M);
    for(int i = 0; i < M; i++){
        grid[i] = (int*)malloc(sizeof(int)*N);
        for(int j = 0; j < N; j++){
            scanf("%d", &grid[i][j]);
        }
    }
    // 初始化访问标记数组,全部设置为false
    bool **visited = (bool**)malloc(sizeof(bool*)*M);
    for(int i = 0; i < M; i++){
        visited[i] = (bool*)malloc(sizeof(bool)*N);
        for(int j = 0; j < N; j++){
            visited[i][j] = false;
        }
    }
    int max_region = 0; // 记录最大连通区域的大小
    // 定义四个方向的移动:上、下、左、右
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
    // 创建队列,最大可能大小为M*N
    Queue *q = createQueue(M*N);
    // 遍历每一个网格点
    for(int i = 0; i < M; i++){
        for(int j = 0; j < N; j++){
            if(!visited[i][j]){
                // 使用BFS计算当前连通区域的大小
                enqueue(q, i, j);
                visited[i][j] = true;
                int count = 1;
                while(!isEmpty(q)){
                    Point p = dequeue(q);
                    int x = p.x;
                    int y = p.y;
                    for(int dir = 0; dir < 4; dir++){
                        int new_x = x + dx[dir];
                        int new_y = y + dy[dir];
                        // 判断新位置是否在网格范围内且未被访问
                        if(new_x >=0 && new_x < M && new_y >=0 && new_y < N && !visited[new_x][new_y]){
                            // 判断编号差的绝对值是否小于等于1
                            if(abs(grid[x][y] - grid[new_x][new_y]) <= 1){
                                enqueue(q, new_x, new_y);
                                visited[new_x][new_y] = true;
                                count++;
                            }
                        }
                    }
                }
                // 更新最大连通区域的大小
                if(count > max_region){
                    max_region = count;
                }
            }
        }
    }
    // 输出结果
    printf("%d\n", max_region);
    // 释放内存
    for(int i = 0; i < M; i++) {
        free(grid[i]);
        free(visited[i]);
    }
    free(grid);
    free(visited);
    free(q->data);
    free(q);
    return 0;
}

九、C++算法源码

// C++版本
#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int M, N;
    // 读取网格的行数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];
        }
    }
    // 初始化访问标记数组,全部设置为false
    vector<vector<bool>> visited(M, vector<bool>(N, false));
    int max_region = 0; // 记录最大连通区域的大小
    // 定义四个方向的移动:上、下、左、右
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
    // 遍历每一个网格点
    for(int i = 0; i < M; i++){
        for(int j = 0; j < N; j++){
            if(!visited[i][j]){
                // 使用BFS计算当前连通区域的大小
                queue<pair<int, int>> q;
                q.push({i, j});
                visited[i][j] = true;
                int count = 1;
                while(!q.empty()){
                    pair<int, int> p = q.front();
                    q.pop();
                    int x = p.first;
                    int y = p.second;
                    for(int dir = 0; dir < 4; dir++){
                        int new_x = x + dx[dir];
                        int new_y = y + dy[dir];
                        // 判断新位置是否在网格范围内且未被访问
                        if(new_x >=0 && new_x < M && new_y >=0 && new_y < N && !visited[new_x][new_y]){
                            // 判断编号差的绝对值是否小于等于1
                            if(abs(grid[x][y] - grid[new_x][new_y]) <= 1){
                                q.push({new_x, new_y});
                                visited[new_x][new_y] = true;
                                count++;
                            }
                        }
                    }
                }
                // 更新最大连通区域的大小
                if(count > max_region){
                    max_region = count;
                }
            }
        }
    }
    // 输出结果
    cout << max_region;
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189738.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LLM】Agent在智能客服的实践(AI agent、记忆、快捷回复 | ReAct)

note 内容概况&#xff1a;结合京粉app学习agent的实践 Agent架构&#xff1a;通过模型训练提升LLM识别工具的准确性&#xff1b;设计可扩展并安全可控的agent架构扩展业务能力。记忆&#xff1a;多轮对话应用中如何组织、存储和检索记忆来提升大模型对用户的理解。快捷回复&…

【JAVA开源】基于Vue和SpringBoot的水果购物网站

本文项目编号 T 065 &#xff0c;文末自助获取源码 \color{red}{T065&#xff0c;文末自助获取源码} T065&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

生产消费者模式

6. 生产消费者模式 Producer-Consumer模式 6.1 概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯&#xff0c;而通过阻塞队列来进行通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔…

解决TortoiseGit文件夹图标不见的问题。

打开注册表&#xff0c;\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ &#xff0c;把里面的TortoiseGit开头的前面多补几个空格&#xff0c;让它们排到靠前的位置&#xff0c;然后重启电脑。 据说是windows只有前11/…

在线点餐堂食系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商品管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;公告信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品&#xff0c;…

AL生成文章标题指定路径保存:创新工具助力内容创作高效启航

在信息爆炸的时代&#xff0c;一个吸引人的标题是文章成功的第一步。它不仅要准确概括文章内容&#xff0c;还要能激发读者的好奇心&#xff0c;促使他们点击阅读。随着人工智能技术的飞速发展&#xff0c;AL生成文章标题功能正逐渐成为内容创作者的新宠&#xff0c;看看它是如…

Mysql数据库--聚合查询、分组查询、联合查询(不同的连接方式)

文章目录 1.查询的进阶版1.1查询搭配插入进行使用1.2聚合查询1.3group by分组查询1.4联合查询之笛卡尔积1.5左外连接&#xff0c;右外连接介绍join on1.6自连表 1.查询的进阶版 1.1查询搭配插入进行使用 我们首先创建两张表&#xff0c;一个叫做student,一个叫做student2,两个…

DenseNet算法:口腔癌识别

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 DenseNet算法结构 其基本思路与ResNet一致&#xff0c;但是它建立的是前面所有层和后面层的密集连接&#xff0c;它的另一大特色是通过特征在channel上的连接来实现特征重用。 二 设计理念 三…

遥感影像-语义分割数据集:云及云阴影数据集详细介绍及训练样本处理流程

原始数据集详情 简介&#xff1a;数据集包括108个GF-1宽幅&#xff08;WFV&#xff09;的云和云阴影掩码&#xff0c;该数据集用于GF-1 WFV图像中的云和云阴影检测。 KeyValue卫星类型高分一宽幅覆盖区域未知场景未知分辨率16m数量108张单张尺寸17344*15627原始影像位深16位标…

如何在银河麒麟服务器中获取关键日志信息

如何在银河麒麟服务器中获取关键日志信息 1、获取messages日志2、获取dmesg输出 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在银河麒麟服务器中&#xff0c;获取messages和dmesg日志是排查问题的重要步骤。 1、dmesg命令用于显示或控制…

【深度学习基础模型】深度残差网络(Deep Residual Networks, DRN)详细理解并附实现代码。

【深度学习基础模型】深度残差网络&#xff08;Deep Residual Networks, DRN&#xff09;详细理解并附实现代码。 【深度学习基础模型】深度残差网络&#xff08;Deep Residual Networks, DRN&#xff09;详细理解并附实现代码。 文章目录 【深度学习基础模型】深度残差网络&a…

C++ | Leetcode C++题解之第457题环形数组是否存在循环

题目&#xff1a; 题解&#xff1a; class Solution { public:bool circularArrayLoop(vector<int>& nums) {int n nums.size();auto next [&](int cur) {return ((cur nums[cur]) % n n) % n; // 保证返回值在 [0,n) 中};for (int i 0; i < n; i) {if …

【人工智能深度学习应用】妙搜API最佳实践

功能概述 AI妙搜通过集成夸克通用搜索引擎&#xff0c;能够提供一个强大的搜索素材功能&#xff0c;大大提升内容创作者在寻找和使用网络资源时的效率和便捷性。用户只需输入相关的关键词或描述&#xff0c;系统将根据用户的搜索词在互联网上进行搜索&#xff0c;并展示与搜索…

【3D目标检测】激光雷达和相机联合标定(一)——ROS同步解包

ROS同步解包 引言1 鱼香ROS一键安装ros-docker脚本&#xff1a;2 指定目录映射3 数据解包3.1 解包脚本3.2 依赖安装3.3 运行脚本&#xff0c;解包 引言 总结步骤如下&#xff1a; 采集同步数据&#xff1a;ROS录制&#xff08;推荐&#xff09;&#xff0c;或者代码同步触发采…

C++入门基础知识99——【关于C++ 成员运算符】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 成员运算符的相关内容&#xff01; 关…

昇思学习打卡营第32天|基于ResNet50的中药炮制饮片质量判断模型

背景介绍 中药炮制是根据中医药理论&#xff0c;依照临床用药需求&#xff0c;通过调剂和制剂要求&#xff0c;将中药材制备成中药饮片的过程。老百姓日常使用的中药饮片&#xff0c;是中药炮制技术的成果。中药炮制过程中&#xff0c;尤其是涉及到水火处理时&#xff0c;必须注…

CNN模型对CIFAR-10中的图像进行分类

代码功能 这段代码展示了如何使用 Keras 和 TensorFlow 构建一个卷积神经网络&#xff08;CNN&#xff09;模型&#xff0c;用于对 CIFAR-10 数据集中的图像进行分类。主要功能包括&#xff1a; 加载数据&#xff1a;从 CIFAR-10 数据集加载训练和测试图像。 数据预处理&#…

HTTP【网络】

文章目录 HTTPURL(Uniform Resource Lacator) HTTP协议格式HTTP的方法HTTP的状态码HTTP常见的Header HTTP 超文本传输协议&#xff0c;是一个简单的请求-响应协议&#xff0c;HTTP通常运行在TCP之上 URL(Uniform Resource Lacator) 一资源定位符&#xff0c;也就是通常所说的…

NIM简单实践-图像分割

项目背景 我正在学习一个图像分割的 Demo&#xff0c;使用 NVIDIA 提供的预训练大模型进行光学字符检测 (OCDNet) 和光学字符识别 (OCRNet)。这些模型专门为光学字符检测和识别设计&#xff0c;能够自动将图像中的字符进行分割和识别。 预训练模型介绍 OCDNet (Optical Char…

Windows NTLM中继攻击(PortBender二进制可执行文件)

Windows NTLM中继攻击&#xff08;PortBender二进制可执行文件) 前言 最近在完善自己的一套TTPs&#xff08;战术、技术和程序&#xff09;以应对未来的网络作战、项目和攻防演练需求&#xff0c;翻到了PortBender&#xff0c;我觉得不依赖C2和影响主机本身实现这一切非常有趣…