机器人活动区域 - 华为OD统一考试

news/2024/7/20 19:21:49 标签: 华为od, 算法, java, python, c++, 面试, 深度优先

OD统一考试

题解: Java / Python / C++

alt

题目描述

现有一个机器人,可放置于 M x 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

题解

这是一个深度优先搜索(DFS)的问题,通过遍历网格中的每个点,使用DFS计算以该点为起点的可活动最大范围。在DFS过程中,通过标记访问数组 vis 来避免重复计数。

解题思路:

  1. 从网格的每一个点出发,进行DFS,计算以该点为起点的可活动最大范围。
  2. 使用DFS时,遍历当前点的四个方向,如果相邻网格的数字编号差值的绝对值小于等于1,并且相邻网格没有被访问过,则可以继续DFS。
  3. 使用一个二维数组 vis 来标记已经访问的网格,防止重复计数。
  4. 遍历所有点,找到最大的可活动范围。

时间复杂度:O(M * N),其中 M 为网格的行数,N 为网格的列数。

空间复杂度:O(M * N),需要额外的二维数组 vis 来标记访问状态。

Java

java">import java.util.Scanner;
/**
 * @author code5bug
 */
public class Main {
    static int m, n;
    static int[][] g;
    static boolean[][] vis;
    static int[] dirs = {-1, 0, 1, 0, -1};

    public static int dfs(int r, int c) {
        if (vis[r][c]) {
            return 0;
        }

        vis[r][c] = true;
        int cnt = 1;

        // 向(r,c)的四个方向拓展
        for (int i = 0; i < 4; ++i) {
            int nr = r + dirs[i];
            int nc = c + dirs[i + 1];

            if (nr >= 0 && nr < m && nc >= 0 && nc < n && !vis[nr][nc] && Math.abs(g[nr][nc] - g[r][c]) <= 1) {
                cnt += dfs(nr, nc);
            }
        }

        return cnt;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        m = scanner.nextInt();
        n = scanner.nextInt();

        g = new int[m][n];
        vis = new boolean[m][n];

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                g[i][j] = scanner.nextInt();
            }
        }

        int maxRange = 0;

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                maxRange = Math.max(maxRange, dfs(i, j));
            }
        }

        System.out.println(maxRange);
    }
}

Python

python">from itertools import pairwise


m, n = map(int, input().split())
g = [list(map(int, input().split())) for _ in range(m)]
# 是否已经被访问计数
vis = [[False] * n for _ in range(m)]
dirs = [-1, 0, 1, 0, -1]


def dfs(r: int, c: int) -> int:
    """机器人在(r, c)可活动的最大范围对应的网格点数目(已经被标记访问就不参与计数,避免重复计数提高性能)"""
    if vis[r][c]:
        return 0

    vis[r][c] = True
    cnt = 1

    # 向(r,c)的四个方向拓展
    for dr, dc in pairwise(dirs):
        nr, nc = r + dr, c + dc
        if 0 <= nr < m and 0 <= nc < n and not vis[nr][nc] and abs(g[nr][nc] - g[r][c]) <= 1:
            cnt += dfs(nr, nc)
    return cnt


max_rage = max([dfs(r, c) for r in range(m) for c in range(n)])
print(max_rage)

C++

#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_M = 150 + 5;
const int MAX_N = 150 + 5;

int m, n;
int g[MAX_M][MAX_N];
bool vis[MAX_M][MAX_N];
const int dirs[] = {-1, 0, 1, 0, -1};

int dfs(int r, int c) {
    if (vis[r][c]) {
        return 0;
    }

    vis[r][c] = true;
    int cnt = 1;

    for (int i = 0; i < 4; ++i) {
        int nr = r + dirs[i];
        int nc = c + dirs[i + 1];

        if (nr >= 0 && nr < m && nc >= 0 && nc < n && !vis[nr][nc] && abs(g[nr][nc] - g[r][c]) <= 1) {
            cnt += dfs(nr, nc);
        }
    }

    return cnt;
}

int main() {
    cin >> m >> n;

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> g[i][j];
        }
    }

    int max_range = 0;

    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            max_range = max(max_range, dfs(i, j));
        }
    }

    cout << max_range << endl;

    return 0;
}

相关练习题

题号题目难易
LeetCode 200200. 岛屿数量中等
LeetCode 827827. 最大人工岛困难

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏


http://www.niftyadmin.cn/n/5295766.html

相关文章

欢迎来到Web3.0的世界:Solidity智能合约安全漏洞分析

智能合约概述 智能合约是运行在区块链网络中的一段程序&#xff0c;经由多方机构自动执行预先设定的逻辑&#xff0c;程序执行后&#xff0c;网络上的最终状态将不可改变。智能合约本质上是传统合约的数字版本&#xff0c;由去中心化的计算机网络执行&#xff0c;而不是由政府…

【2023湖南大学ACM新生赛】A.Yin Yang number(阴阳数)

这是考试的时候的源代码。我考试的时候用的解法属于走捷径了&#xff0c;使用了C模板容器bitset&#xff0c;将输入的无符号长整数unsigned long long直接转化为64位bitset&#xff0c;然后求各位和。 #include <iostream> #include <bitset>using namespace std;…

[leetcode ~go]三数之和 M

:::details 给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;请你找出所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 示例 1&#xff1a; …

LeetCode1572. Matrix Diagonal Sum

文章目录 一、题目二、题解 一、题目 Given a square matrix mat, return the sum of the matrix diagonals. Only include the sum of all the elements on the primary diagonal and all the elements on the secondary diagonal that are not part of the primary diagona…

腾讯云50G通用型SSD云硬盘够用吗?

腾讯云服务器系统盘是50G通用型SSD云硬盘&#xff0c;50G系统盘够用吗&#xff1f;够用。一般来讲&#xff0c;Windows操作系统占用空间更大&#xff0c;系统盘要50GB起步&#xff1b;Linux操作系统占用空间较少&#xff0c;系统盘为20GB起步。所以&#xff0c;如果仅仅是用来安…

Oracle数据库19c OCP 1z0-082考场真题解析第19题

考试科目&#xff1a;1Z0-082 考试题量&#xff1a;90 通过分数&#xff1a;60% 考试时间&#xff1a;150min 本文为云贝教育郭一军guoyJoe原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。【云贝教育】Orac…

5. 数据结构

5. 数据结构 本章详细讨论了你已经学过的一些知识&#xff0c;同样也添加了一些新内容。 5.1. 关于列表更多的内容 Python 的列表数据类型包含更多的方法。这里是所有的列表对象方法&#xff1a; list.append(x) 把一个元素添加到链表的结尾&#xff0c;相当于 a[len(a):]…