华为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;
	}
}
相关推荐
倒头就睡的小比特13 小时前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!13 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼14 小时前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光15 小时前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark15 小时前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her115 小时前
并查集-听课笔记
笔记·算法·并查集
码流子16 小时前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven16 小时前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark16 小时前
从算法设计模式看编程思维的抽象能力4
算法
2601_9622186116 小时前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法