华为OD E卷(100分)22-机器人的活动区域

前言

工作了十几年,从普通的研发工程师一路成长为研发经理、研发总监。临近40岁,本想辞职后换一个相对稳定的工作环境一直干到老, 没想到离职后三个多月了还没找到工作,愁肠百结。为了让自己有点事情做,也算提高一下自己的编程能力,无聊之余打算用一些大厂的编程题练练手。希望通过这些分享能够帮到一些人,也希望能和看到此文的大神们沟通交流,提升自己,更希望在此期间能够找到一份理想的工作。

题目描述

现有一个机器人,可放置于 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 个数字,表示最大活动区域的网格点数目,行首行尾无多余空格。

示例

示例1

输入

4 4

1 2 5 2

2 4 4 5

3 5 7 1

4 6 2 4

输出

6

说明

|---|---|---|---|
| 1 | 2 | 5 | 2 |
| 2 | 4 | 4 | 5 |
| 3 | 5 | 7 | 1 |
| 4 | 6 | 2 | 4 |

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

示例1

输入

2 3

1 3 5

4 1 3

输出

1

说明

任意两个相邻网格的差值绝对值都大于1,机器人不能在网格间移动,只能在单个网格内活动,对应网格点数目为1

解题思路

定义上下左右方向,使用DFS搜索算法进行探索,取最大路径数。

题解

Java实现

java 复制代码
package huawei.e100;

import java.util.Arrays;
import java.util.Scanner;

/**
* @author arnold
* @date 2024年12月14日

*/
public class T22 {
	
	static final int[][] OFFSET = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			int m = sc.nextInt();
			int n = sc.nextInt();
			int[][] data = new int[m][n];
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++) {
					data[i][j] = sc.nextInt();
				}
			}
			
			int maxCanPlayEara = 0;
            // 对所有格子逐个探索,取步数最大值
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++) {
					boolean[][] dataUsed = new boolean[m][n];
					int canPlayCount = run(data, m, n, i, j, dataUsed);
					maxCanPlayEara = Math.max(maxCanPlayEara, canPlayCount);
				}
			}
			System.out.println(maxCanPlayEara);
						
		}
	}
	
	static int run(int[][] data, int m, int n, int startM, int startN, boolean[][] dataUsed) {
		int canPlayCount = 1; // 定义活动范围
		dataUsed[startM][startN] = true; // 标记当前点已经访问过
		// 遍历四个方向
		for(int[] d :OFFSET) {
			int dm = startM + d[0];
			int dn = startN + d[1];
			// 到达边界跳过。
			if (dm < 0 || dm >=m || dn <0 || dn >= n) {
				continue;
			}
			if (Math.abs(data[dm][dn] - data[startM][startN]) <=1 && dataUsed[dm][dn] == false) {
				canPlayCount += run(data, m, n, dm, dn, dataUsed);
			}
		}
		return canPlayCount;
	}
}
相关推荐
大数据追光猿9 分钟前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!26 分钟前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉27 分钟前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生27 分钟前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴32 分钟前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing32 分钟前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财33 分钟前
加油站(力扣134)
算法·leetcode·职场和发展
王老师青少年编程33 分钟前
【GESP C++八级考试考点详细解读】
数据结构·c++·算法·gesp·csp·信奥赛
qy发大财34 分钟前
柠檬水找零(力扣860)
算法·leetcode·职场和发展
瓦力的狗腿子37 分钟前
Starlink卫星动力学系统仿真建模番外篇6-地球敏感器
算法·数学建模·simulink