| 题目 | 机器人活动区域 |
| 难度 | 难 |
| 题目说明 | 有一个机器人,可放置于 M x N 的网格中任意位置,每个网格包含一个非负整数编号,当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可以在网格间移动。 求机器人可活动的最大范围对应的网络点数目。 说明:机器人之鞥你在相邻网格间上、下、左、右移动。 示例,输入如下网格: ![]() 输出:6 说明:图中绿色区域,相邻网格差值的绝对值小于或等于 1,且为最大区域,对应的网格个数为 6。 示例 2,输入以下网格: ![]() 输出: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 |
| 说明 | 任意两个相邻网格之差的绝对值都大于 1,机器人无法移动,最大区域对应网格点个数为 1。 |
题目解读:
此题要求从一个二维的网格中,找出 1 到多个区域,确保每个区域中相邻格子的数字之差不大于 1。
分析与思路:
在 Windows 95 上,有一款经典的扫雷游戏,点下一个方块,如果这个方块不是地雷,就会显示它周围(8个方向)的地雷总数,如果它附近没有地雷,那么周围 8 个方向的方块也会自动点开,如果这 8 个方向的方块……。
在算法上,此题与扫雷算法类似。
可以从网格中的一个格子开始,采用遍历的方式(深度遍历或广度遍历都可以),获取与它相邻的所有数字之差不大于 1 的格子,直到找到所有符合条件的格子,或整个网格中所有的格子都已经遍历完毕,此时,就找到了一个符合条件的区域。
接下来,从网格中找到下一个(没有遍历过)不在任何区域中的点,以这个点为始点,继续遍历,寻找与它相邻数字不大于 1 的格子,直到找到第二个区域。
按照相同的方法,找到所有的区域。最后,找出格子最多的区域,输出其格子数。
需要注意:使用的格子,在下次判断的时候,不应重复统计。
Java代码
- import java.util.Scanner;
-
- /**
- * 机器人活动区域
- * @since 2023.09.26
- * @version 0.1
- * @author Frank
- *
- */
- public class RobotMoveArea {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- while (sc.hasNext()) {
- // 第一行输入一串数字,以空格分隔
- String line = sc.nextLine();
- String[] rec = line.split(" ");
-
- int rowCnt = Integer.parseInt( rec[0] );
- int columnCnt = Integer.parseInt( rec[1] );
-
- int[][] area = new int[rowCnt][columnCnt];
- for( int i = 0; i < rowCnt; i ++ )
- {
- String row = sc.nextLine();
- String[] columns = row.split(" ");
- for( int j = 0; j < columnCnt; j ++ )
- {
- area[i][j] = Integer.parseInt( columns[j] );
- }
- }
- processRobotMoveArea( area);
- }
-
- }
-
- private static void processRobotMoveArea( int[][] area ) {
- int maxPartAreaCnt = 0;
-
- for( int i = 0; i < area.length; i ++ )
- {
- for( int j = 0; j < area[i].length; j ++ )
- {
- int cellValue = area[i][j];
- if( cellValue == -1 )
- {
- continue;
- }
- int partAreaCnt = getPartAraCnt( i, j , area );
- if( partAreaCnt > maxPartAreaCnt )
- {
- maxPartAreaCnt = partAreaCnt;
- }
- }
- }
- System.out.println( maxPartAreaCnt );
-
- }
-
- private static int getPartAraCnt( int i, int j, int[][] area ) {
- int areaCnt = 0;
- int rowCnt = area.length;
- int columnCnt = area[0].length;
- int cellValue = area[i][j];
-
- area[i][j] = -1;
- areaCnt ++;
- if( i > 0 && area[i - 1][j] != -1 && Math.abs(cellValue - area[i - 1][j]) <= 1 )
- {
- areaCnt += getPartAraCnt( i - 1, j, area );
- }
- if( i < rowCnt - 1 && area[i + 1][j] != -1 && Math.abs(cellValue - area[i + 1][j]) <= 1)
- {
- areaCnt += getPartAraCnt( i + 1, j, area );
- }
-
- if( j > 0 && area[i][j - 1 ] != -1 && Math.abs(cellValue - area[i][j-1]) <= 1) {
- areaCnt += getPartAraCnt( i, j - 1, area );
- }
-
- if( j < columnCnt - 1 && area[i][j + 1] != -1 && Math.abs(cellValue - area[i][j + 1]) <= 1)
- {
- areaCnt += getPartAraCnt( i, j + 1, area );
- }
-
- return areaCnt;
- }
-
- }
JavaScript代码
- const rl = require("readline").createInterface({ input: process.stdin });
- var iter = rl[Symbol.asyncIterator]();
- const readline = async () => (await iter.next()).value;
- void async function() {
- while (line = await readline()) {
-
- var rec = line.split(" ");
- var rowCnt = parseInt(rec[0]);
- var columnCnt = parseInt(rec[1]);
-
- // 第二行数据, 矩形区域
- var area = new Array();
- for (var i = 0; i < rowCnt; i++) {
- line = await readline();
- var columns = line.split(" ");
- var columnValues = new Array();
- for (var j = 0; j < columnCnt; j++) {
- columnValues[j] = parseInt(columns[j]);
- }
- area[i] = columnValues;
- }
-
- processRobotMoveArea(area);
- }
-
- }();
-
- function processRobotMoveArea(area) {
- var maxPartAreaCnt = 0;
-
- for (var i = 0; i < area.length; i++) {
- for (var j = 0; j < area[i].length; j++) {
- var cellValue = area[i][j];
- if (cellValue == -1) {
- continue;
- }
- var partAreaCnt = getPartAraCnt(i, j, area);
- if (partAreaCnt > maxPartAreaCnt) {
- maxPartAreaCnt = partAreaCnt;
- }
- }
- }
- console.log(maxPartAreaCnt);
- }
-
- function getPartAraCnt(i, j, area) {
- var areaCnt = 0;
- var rowCnt = area.length;
- var columnCnt = area[0].length;
- var cellValue = area[i][j];
-
- area[i][j] = -1;
- areaCnt++;
- if (i > 0 && area[i - 1][j] != -1 && Math.abs(cellValue - area[i - 1][j]) <= 1) {
- areaCnt += getPartAraCnt(i - 1, j, area);
- }
- if (i < rowCnt - 1 && area[i + 1][j] != -1 && Math.abs(cellValue - area[i + 1][j]) <= 1) {
- areaCnt += getPartAraCnt(i + 1, j, area);
- }
-
- if (j > 0 && area[i][j - 1] != -1 && Math.abs(cellValue - area[i][j - 1]) <= 1) {
- areaCnt += getPartAraCnt(i, j - 1, area);
- }
-
- if (j < columnCnt - 1 && area[i][j + 1] != -1 && Math.abs(cellValue - area[i][j + 1]) <= 1) {
- areaCnt += getPartAraCnt(i, j + 1, area);
- }
-
- return areaCnt;
- }
(完)