全网最全面的华为OD机试真题汇总,100%原题题库,不需要开会员即可查看全部内容,更多考题请查看真题库。
真题库:https://www.yuque.com/codernav.com/od
题目:机器人活动区域
知识点深搜广搜
时间限制:1s 空间限制:256MB 限定语言:不限
题目描述:
现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可在网格间移动
问题:求机器人可活动的最大范围对应的网格点数目。
说明:
1)网格左上角坐标为 (0, 0),右下角坐标为 (m-1, n-1)
2)机器人只能在相邻网格间上、下、左、右移动
示例1,输入如下网格
输出:6
说明:图中绿色区域,相邻网格差值绝对值都小于等于1,且为最大区域,对应网格点数目为6
示例 2,输入如下网格:
输出:1
说明:任意两个相邻网格的差值绝对值都大于1,机器人不能在网格间移动,只能在单个网格内活动,对应网格点数目为 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,最大区域对应网格点数目为 6
示例2
输入:
2 3
1 3 5
4 1 3
输出:
1
说明:
见前面描述中示例 2,最大区域对应网格点数目为 1
解题思路:
使用深度搜索求出所有机器人可活动区域大小,找出其中最大值。
代码实现一:
package com.codernav.demo.hwod.exam; import java.util.Scanner; /** * @title 机器人活动区域 * @Description 现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。 * 当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可在网格间移动 * 问题:求机器人可活动的最大范围对应的网格点数目。 * @Author 开发者导航 * @website https://codernav.com * @date 2023/5/28 */ public class Main { public static int[][] region; public static int M; public static int N; public static void main(String[] args) { Scanner sc = new Scanner(System.in); M = sc.nextInt(); N = sc.nextInt(); region = new int[M][N]; for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { region[i][j] = sc.nextInt(); } } int max = 0; //最大活动区域 for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { if (region[i][j] != -1) { max = Math.max(max, move(i, j, region[i][j])); } } } System.out.println(max); } /** * @param row 横坐标 * @param col 纵坐标 * @param num 上个网格的数字编号 * @return 活动区域大小 */ public static int move(int row, int col, int num) { if (row < 0 || col < 0 || row >= M || col >= N ) { return 0; //越界了,返回0 } int currentNum = region[row][col]; if (currentNum == -1 || //已经统计过的网格 Math.abs(currentNum - num) > 1) { //不符合绝对差值小于等于1 return 0; } region[row][col] = -1; //已经统计过的网格置为-1 int count = 1; //符合要求的网格统计1 count += move(row - 1, col, currentNum); //向上 count += move(row + 1, col, currentNum); //向下 count += move(row, col - 1, currentNum); //向左 count += move(row, col + 1, currentNum); //向右 return count; } }
代码实现二:Java代码满分实现
package com.codernav.demo.hwod.exam; import java.util.Scanner; /** * @title 机器人活动区域 * @Description 现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。 * 当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可在网格间移动 * 问题:求机器人可活动的最大范围对应的网格点数目。 * @Author 开发者导航 * @website https://codernav.com * @date 2023/5/28 */ public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextInt()) { int m = in.nextInt(); int n = in.nextInt(); int[][][] arr = new int[m][n][2]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arr[i][j][0] = in.nextInt(); arr[i][j][1] = 0; } } int ans = 0; int tempAns = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int[][][] temp = arr; tempAns = change(temp, i, j, 0); ans = Math.max(tempAns, ans); } } System.out.println(ans); } } static int change(int[][][] arr, int i, int j, int size) { if (arr[i][j][1] == 0) { arr[i][j][1] = 1; size += 1; if (i - 1 >= 0 && Math.abs(arr[i - 1][j][0] - arr[i][j][0]) <= 1 && arr[i - 1][j][1] == 0) { //上 size += change(arr, i - 1, j, 0); } if (i + 1 < arr.length && Math.abs(arr[i + 1][j][0] - arr[i][j][0]) <= 1 && arr[i + 1][j][1] == 0) { //下 size += change(arr, i + 1, j, 0); } if (j - 1 >= 0 && Math.abs(arr[i][j][0] - arr[i][j - 1][0]) <= 1 && arr[i][j - 1][1] == 0) { //左 size += change(arr, i, j - 1, 0); } if (j + 1 < arr[0].length && Math.abs(arr[i][j][0] - arr[i][j + 1][0]) <= 1 && arr[i][j + 1][1] == 0) { //右 size += change(arr, i, j + 1, 0); } } return size; } }