华为OD机考算法题:机器人活动区域

题目部分

题目 机器人活动区域
难度
题目说明 有一个机器人,可放置于 M x N 的网格中任意位置,每个网格包含一个非负整数编号,当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可以在网格间移动。
求机器人可活动的最大范围对应的网络点数目。
说明:机器人之鞥你在相邻网格间上、下、左、右移动。
示例,输入如下网格:

华为OD机考算法题:机器人活动区域_第1张图片
输出:6
说明:图中绿色区域,相邻网格差值的绝对值小于或等于 1,且为最大区域,对应的网格个数为 6。


示例 2,输入以下网格:
华为OD机考算法题:机器人活动区域_第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;
}

(完)

你可能感兴趣的:(华为OD机考,华为od,算法,数据结构,Java,Javascript)