【华为OD-E卷-机器人活动区域 100分(python、java、c++、js、c)】

ops/2024/12/28 19:01:57/

javacjsc_0">【华为OD-E卷-机器人活动区域 100分(python、java、c++、js、c)】

题目

现有一个机器人,可放置于 M × N 的网格中任意位置,每个网格包含一个非负整数编号,当相邻网格的数字编号差值的绝对值小于等于 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 个数字,表示最大活动区域的网格点数目,

行首行尾无多余空格

用例

用例一:
输入:
4 4
1 2 5 2
2 4 4 5
3 5 7 1
4 6 2 4
输出:
6
用例二:
输入:
2 3
1 3 5
4 1 3
输出:
1

python解法

  • 解题思路:
  • 问题分析:

给定一个矩阵,每个元素代表一个数字,我们需要找出矩阵中最大区域的大小。该区域由相邻的元素组成,两个相邻的元素的差的绝对值必须小于等于 1。区域中的元素可以通过上下左右四个方向相邻。
思路:

广度优先搜索 (BFS):我们可以从矩阵中的每个未访问的元素开始,使用 BFS 遍历所有与其差值小于等于 1 的相邻元素,找出一个连通区域,计算该区域的大小。
最大区域:遍历矩阵中每个未访问的元素,执行 BFS,更新最大区域的大小。
细节:

BFS 的实现:使用队列 queue 来进行 BFS,每次从队列中取出一个元素,检查其四个方向的相邻元素,如果满足条件(未访问且差值小于等于 1),将其加入队列。
visited 数组:用来标记矩阵中哪些元素已经被访问,避免重复遍历。
复杂度:假设矩阵的大小为 m * n,由于每个元素最多被访问一次,时间复杂度为 O(m * n)。

from collections import deque# 使用广度优先搜索 (BFS) 计算一个连通区域的大小
def bfs(matrix, visited, i, j, m, n):queue = deque([(i, j)])  # 初始化队列,开始节点是 (i, j)count = 0  # 当前区域的元素计数offsets = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # 上下左右四个方向的偏移量while queue:x, y = queue.popleft()  # 弹出队列中的元素 (x, y)if visited[x][y]:  # 如果该点已经访问过,跳过continuevisited[x][y] = True  # 标记该点为已访问count += 1  # 计数当前区域的元素数量# 遍历四个方向的相邻点for offsetX, offsetY in offsets:newX, newY = x + offsetX, y + offsetY  # 计算相邻点的坐标if 0 <= newX < m and 0 <= newY < n and not visited[newX][newY]:  # 确保新点在矩阵范围内并且未被访问if abs(matrix[x][y] - matrix[newX][newY]) <= 1:  # 如果当前点与新点的差值小于等于1queue.append((newX, newY))  # 将新点加入队列继续扩展return count  # 返回当前连通区域的大小# 查找矩阵中最大的连通区域
def find_largest_area(matrix, m, n):visited = [[False for _ in range(n)] for _ in range(m)]  # 初始化访问标记数组max_area = 0  # 存储最大区域的大小# 遍历整个矩阵for i in range(m):for j in range(n):if not visited[i][j]:  # 如果当前点没有被访问过# 执行 BFS,计算当前连通区域的大小max_area = max(max_area, bfs(matrix, visited, i, j, m, n))return max_area  # 返回最大区域的大小# 输入矩阵的尺寸 m 和 n
m, n = map(int, input().split())
# 输入矩阵内容
matrix = [list(map(int, input().split())) for _ in range(m)]# 输出最大连通区域的大小
print(find_largest_area(matrix, m, n))

java_125">java解法

  • 解题思路
  • 问题分析:
    给定一个 m x n 的矩阵 grid,我们需要找出矩阵中最大的“区域”,区域中的元素满足以下条件:任意两个相邻元素的差值不大于 1,且区域内的元素必须是连通的(即它们通过上下左右方向相邻)。
    思路:
    我们可以使用 广度优先搜索 (BFS) 来探索每个未访问的区域。BFS 会遍历与当前点差值不大于 1 的所有相邻点,并计算区域的大小。
    最大区域:遍历整个矩阵,对于每一个未访问的点,执行一次 BFS,计算该区域的大小,并更新最大区域的大小。
    细节:
    使用一个 visited 数组记录哪些点已经访问过,避免重复计算。
    通过一个队列实现 BFS,探索上下左右相邻点。
    每次 BFS 执行时,如果当前点与相邻点的差值小于等于 1,则将该相邻点加入队列进行进一步遍历。
    复杂度:假设矩阵的大小为 m x n,每个点最多被访问一次,BFS 的复杂度是 O(m * n),因此总时间复杂度为 O(m * n)。
java">import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取矩阵的行数和列数int m = sc.nextInt();int n = sc.nextInt();// 读取矩阵内容int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = sc.nextInt();}}// 输出最大区域的大小System.out.println(getResult(grid, m, n));}// 计算矩阵中最大的连通区域的大小public static int getResult(int[][] grid, int m, int n) {boolean[][] visited = new boolean[m][n]; // 访问标记数组int maxSize = 0;  // 记录最大的区域大小// 四个方向的偏移量,上下左右int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};// 遍历整个矩阵for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {// 如果当前点没有被访问过,执行 BFS 计算该区域的大小if (!visited[i][j]) {int size = bfs(grid, visited, i, j, m, n, dirs);// 更新最大区域的大小maxSize = Math.max(maxSize, size);}}}return maxSize;  // 返回最大的区域大小}// 使用 BFS 查找从 (x, y) 出发的连通区域的大小private static int bfs(int[][] grid, boolean[][] visited, int x, int y, int m, int n, int[][] dirs) {Queue<int[]> queue = new LinkedList<>();  // BFS 使用的队列queue.offer(new int[]{x, y});  // 将起始点加入队列visited[x][y] = true;  // 标记起始点为已访问int size = 1;  // 当前区域的大小,从起始点开始// 当队列不为空时,继续遍历while (!queue.isEmpty()) {int[] point = queue.poll();  // 弹出队列中的一个元素// 遍历当前点的四个方向for (int[] dir : dirs) {int newX = point[0] + dir[0];  // 计算新点的横坐标int newY = point[1] + dir[1];  // 计算新点的纵坐标// 确保新点在矩阵范围内,并且未被访问过// 同时新点与当前点的差值小于等于 1,才将新点加入队列if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY]&& Math.abs(grid[point[0]][point[1]] - grid[newX][newY]) <= 1) {visited[newX][newY] = true;  // 标记新点为已访问queue.offer(new int[]{newX, newY});  // 将新点加入队列size++;  // 增加当前区域的大小}}}return size;  // 返回当前区域的大小}
}

C++解法

  • 解题思路
更新中

C解法

  • 解题思路

  • 问题分析:

给定一个 m x n 的矩阵 values,其中每个元素代表一个数字。我们需要计算矩阵中所有符合条件的连通区域的大小,区域中的元素需要满足以下条件:
任意两个相邻元素的差值不大于 1。
相邻元素通过上下左右方向相连。
思路:

我们可以使用 深度优先搜索 (DFS) 来遍历每个连通区域。DFS 从一个未访问的点开始,探索所有符合条件的相邻点,直到无法再扩展为止。每次 DFS 执行完后,我们可以得到一个连通区域的大小。
最大区域:遍历整个矩阵,找到最大的连通区域,更新最大区域的大小。
细节:

使用一个 traversed 数组来标记哪些元素已经访问过,避免重复计算。
每次 DFS 调用时,如果当前点与相邻点的差值小于等于 1,则递归访问相邻点。
通过四个方向的偏移量 (shifts) 来控制上下左右方向的探索。
复杂度:假设矩阵的大小为 rows x cols,每个点最多被访问一次,因此时间复杂度是 O(rows * cols),即 O(n),其中 n 是矩阵中的元素个数。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>#define MAX_DIM 150  // 定义矩阵的最大尺寸int rows, cols;  // 矩阵的行数和列数
int values[MAX_DIM][MAX_DIM];  // 存储矩阵的值
bool traversed[MAX_DIM][MAX_DIM] = {false};  // 访问标记数组,初始状态下所有元素都没有被访问
int shifts[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};  // 上下左右四个方向的偏移量// 深度优先搜索 (DFS) 函数,用来计算从 (r, c) 出发的连通区域的大小
int depth_search(int r, int c, int steps) {for (int d = 0; d < 4; d++) {  // 遍历四个方向int next_r = r + shifts[d][0];  // 计算下一个行坐标int next_c = c + shifts[d][1];  // 计算下一个列坐标// 判断新点是否在矩阵范围内,且与当前点的差值小于等于 1,并且没有被访问过if (next_r >= 0 && next_r < rows && next_c >= 0 && next_c < cols &&abs(values[next_r][next_c] - values[r][c]) <= 1 && !traversed[next_r][next_c]) {traversed[next_r][next_c] = true;  // 标记新点为已访问steps = depth_search(next_r, next_c, steps + 1);  // 递归访问新点,增加区域大小}}return steps;  // 返回当前连通区域的大小
}int main() {// 输入矩阵的尺寸scanf("%d %d", &rows, &cols);// 输入矩阵的元素for (int r = 0; r < rows; r++) {for (int c = 0; c < cols; c++) {scanf("%d", &values[r][c]);}}int max_region = 0;  // 记录最大区域的大小// 遍历整个矩阵,寻找未访问的点,并执行 DFS 计算连通区域的大小for (int r = 0; r < rows; r++) {for (int c = 0; c < cols; c++) {// 如果当前点没有被访问过,执行 DFS 查找连通区域if (!traversed[r][c]) {traversed[r][c] = true;  // 标记当前点为已访问int region = depth_search(r, c, 1);  // 从当前点开始 DFS,区域初始大小为 1if (region > max_region) max_region = region;  // 更新最大区域大小}}}// 输出最大区域的大小printf("%d\n", max_region);return 0;
}

JS解法

  • 解题思路

javascript">更新中

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏


http://www.ppmy.cn/ops/144616.html

相关文章

Go语言gRPC与gozero的api

什么是gRPC&#xff1f; gRPC是由Google开发并开源的一个高性能、通用的RPC框架。它基于HTTP/2协议&#xff0c;默认使用Protocol Buffers&#xff08;简称ProtoBuf&#xff09;作为接口描述语言&#xff08;IDL&#xff09;。 gRPC的主要特点&#xff1a; 高性能&#xff1a;得…

B2HGraphicBufferProducer和H2BGraphicBufferProducer

在 Android 的图形系统中&#xff0c;B2HGraphicBufferProducer 和 BnGraphicBufferProducer 是基于 Binder 机制的两个重要组件&#xff0c;它们负责图形缓冲区的生产接口。二者关系可以理解为 桥接和实现分离&#xff0c;以下是详细说明&#xff1a; 1. B2HGraphicBufferProd…

flink sink kafka

接上文&#xff1a;一文说清flink从编码到部署上线 之前写了kafka source&#xff0c;现在补充kafka sink。完善kafka相关操作。 环境说明&#xff1a;MySQL&#xff1a;5.7&#xff1b;flink&#xff1a;1.14.0&#xff1b;hadoop&#xff1a;3.0.0&#xff1b;操作系统&#…

计算材料学和分子动力学(MD)

文章目录 1. 计算材料学1. 什么是计算材料学2. 计算材料学尺度1. 纳观尺度2. 微观尺度3. 介观尺度4. 宏观尺度 2.分子动力学1.什么是分子动力学1. 历史上第一个分子动力学模拟2.第一个连续势场的分子动力学模拟3.第一个Lennard-Jones势分子动力学模拟 2.分子动力学的并行3.常用…

.net core sdk 项目多版本切换

使用global.json文件指定项目要使用的sdk版本&#xff1a; 在项目根目录下执行cmd命令&#xff08;sdk的版本默认为当前使用的最新的sdk的版本&#xff09; 默认sdk&#xff1a;dotnet new globaljson指定sdk&#xff1a;dotnet new globaljson --sdk-version <version>…

【Git】-- 版本说明

Alpha&#xff1a;是内部测试版,一般不向外部发布,会有很多 Bug .一般只有测试人员使用。Beta&#xff1a;也是测试版&#xff0c;这个阶段的版本会一直加入新的功能。在 Alpha 版之后推出。RC&#xff1a;(Release Candidate) 顾名思义么 ! 用在软件上就是候选版本。系统平台…

QT信号槽

目录 概念 函数原型 实现 3.1 自带信号→自带槽 3.2 自带信号→自定义槽 3.3 自定义信号 信号槽传参 对应关系 5.1 一对多 5.2 多对一 信号槽的优势 信号槽的注意事项 概念 信号和槽是Qt框架在C语言基础上扩展的一种机制&#xff0c;用于对象之间的通信。这一机制类…

SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…