华为OD机试 - 小华最多能得到多少克黄金 - 深度优先搜索DFS (Java 2024 D卷 200分)

在这里插入图片描述

华为OD机试 2024D卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试、为什么这大题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

小华按照地图去寻宝,地图上被划分成 m 行和 n 列的方格,横纵坐标范围分别是 [0, n−1]和[0, m-1]。在横坐标和纵坐标的数位之和不大于k的方格中存在黄金(每个方格中仅存在一克黄金),但横坐标和纵坐标之和大于k的方格存在危险不可进入。小华从入口(0,0)进入,任何时候只能向左,右,上,下四个方向移动一格。请问小华最多能获得多少克黄金?

二、输入描述

坐标取值范围如下:

0<=m<=50

0<=n<=50

k的取值范围如下:

0<=k<=100

输入中包含3个字数,分别是m,n,k

三、输出描述

最多能获得多少克黄金

四、测试用例

1、输入

40 40 18

2、输出

1484

3、说明

  1. 地图大小为 40x40。
  2. k 值为 18,表示坐标数位之和不大于 18 的格子中有黄金。
  3. 从 (0,0) 开始,通过 DFS 访问所有可以到达的格子,统计总的黄金数量。
  4. 最终收集到的黄金数量为 1484 克。

五、解题思路

1、深度优先搜索DFS

深度优先搜索DFS适用哪些场景?

(1)图的遍历:

DFS 是一种经典的图遍历算法,适用于需要访问图中所有节点的场景。例如,查找连通分量、路径查找等。

(2)树的遍历:

DFS 也适用于树结构的遍历,如前序遍历、中序遍历和后序遍历。用于解决树形结构的问题,如二叉树的深度、最大路径和等。

(3)连通分量:

用于查找图中的连通分量,即从一个节点出发,可以访问到的所有节点。

(4)路径和可达性问题:

用于寻找从起点到终点的路径,判断图中节点之间是否可达。例如迷宫问题、网络可达性等。

(5)拓扑排序:

在有向无环图中,DFS 可用于拓扑排序。

(6)回溯算法:

DFS 可以作为回溯算法的一部分,适用于解决组合问题、子集问题、排列问题等。例如八皇后问题、数独、解迷宫等。

(7)强连通分量:

用于求解有向图中的强连通分量,如 Tarjan 算法、Kosaraju 算法。

深度优先搜索DFS有哪些注意事项?

(1)避免重复访问:

在遍历过程中,需要标记已经访问过的节点,以避免重复访问,导致无限循环。可以使用布尔数组或集合来记录访问状态。

(2)递归深度:

在使用递归实现 DFS 时,需注意递归深度。如果图的深度过大,可能导致栈溢出。可以考虑使用显式栈来模拟递归过程。

(3)空间复杂度:

DFS 的空间复杂度主要取决于递归深度或显式栈的大小。对于非常深的图或树,需注意内存的使用。

(4)处理环:

在有向图中,需注意环的存在,避免在遍历过程中陷入无限循环。通常通过标记节点访问状态来处理。

(5)边界条件:

在递归过程中,需要处理好边界条件,确保递归能够正确结束。

(6)全局变量的使用:

在递归实现中,若使用全局变量存储结果,需要确保在每次递归调用前后维护其状态,避免影响其他递归分支。

(7)图的表示:

确保图的表示(如邻接矩阵、邻接表)能够高效地支持边的访问操作。

2、为什么采用深度优先搜索DFS?

本题的目的是在给定的二维网格地图上,从起点 (0,0) 出发,收集尽可能多的黄金。黄金分布在横坐标和纵坐标数位之和不大于 k 的格子中,移动只能在上下左右四个方向。通过深度优先搜索(DFS)来遍历所有满足条件的格子,记录并统计可以收集的黄金数量。

DFS 是一种经典的图遍历算法,适用于需要访问图中所有节点的场景。在本题中,DFS 可以用来遍历从起点 (0,0) 出发的所有满足条件的格子。

DFS 能够深入到图的每一个分支,找到所有与起始节点连通的节点。在本题中,从起点 (0,0) 开始,通过递归查找所有可以到达的格子。

对于每个格子,DFS 可以有效地访问所有满足条件的相邻格子,确保所有可能的路径都被探索。

3、具体步骤:

  1. 从起点 (0,0) 开始,如果当前格子的数位之和满足条件且未被访问,则收集黄金,并标记为已访问。
  2. 递归地访问四个相邻格子(上、下、左、右)。
  3. 统计并返回当前格子和所有相邻格子能收集的黄金数量。

六、Java算法源码

public class OdTest {
    // 定义方向数组,表示上下左右四个方向
    private static final int[] dx = {0, 0, -1, 1};
    private static final int[] dy = {-1, 1, 0, 0};

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

        // 读取输入
        int m = scanner.nextInt();
        int n = scanner.nextInt();
        int k = scanner.nextInt();

        // 记录访问状态的二维数组
        boolean[][] visited = new boolean[m][n];

        // 从起点(0,0)开始深度优先搜索
        int goldCount = dfs(0, 0, m, n, k, visited);

        // 输出结果
        System.out.println(goldCount);
    }

    // 计算坐标数位之和的辅助函数
    private static int digitSum(int x) {
        int sum = 0;
        while (x != 0) {
            sum += x % 10;
            x /= 10;
        }
        return sum;
    }

    // 深度优先搜索函数
    private static int dfs(int x, int y, int m, int n, int k, boolean[][] visited) {
        // 检查边界和数位之和的限制
        if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y] || (digitSum(x) + digitSum(y) > k)) {
            return 0;
        }

        // 标记当前格子为已访问
        visited[x][y] = true;

        // 初始化黄金数量
        int goldCount = 1; // 当前格子有1克黄金

        // 递归访问四个方向的相邻格子
        for (int i = 0; i < 4; i++) {
            goldCount += dfs(x + dx[i], y + dy[i], m, n, k, visited);
        }

        return goldCount;
    }
}

七、效果展示

1、输入

10 10 5

2、输出

21

3、说明

地图大小为 10x10。
k 值为 5,表示坐标数位之和不大于 5 的格子中有黄金。
从 (0,0) 开始,通过 DFS 访问所有可以到达的格子,统计总的黄金数量。
最终收集到的黄金数量为 21 克。
在这里插入图片描述


🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 D卷 200分)

🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试、为什么这大题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值