华为OD机考双机位A卷- 中庸行者(Java & Python& JS & C/C++ & GO )

最新华为上机考试

真题目录:点击查看目录
华为OD面试真题精选:点击立即查看
2025华为od机试双机位A卷 -华为OD上机考试双机位A卷

题目描述

给定一个m*n的整数矩阵作为地图,矩阵数值为地形高度中庸行者选择地图中的任意一点作为起点,尝试往上、下、左、右四个相邻格子移动;移动时有如下约束:

  • 中庸行者只能上坡或者下坡,不能走到高度相同的点
  • 不允许连续上坡或者连续下坡,需要交替进行
  • 每个位置只能经过一次,不能重复行走

请给出中庸行者在本地图内,能连续移动的最大次数

输入描述

第一行两个数字,分别为行数和每行的列数;

后续数据为矩阵地图内容

矩阵边长范围1-8,地形高度范围0-100000

输出描述

一个整数,代表中庸行者在本地图内,能连续移动的最大次数

示例1

输入

2 2 
1 2
4 3

输出

3

说明

示例2

输入

3 3
1 2 4
3 5 7
6 8 9

输出

4

说明

解题思路


题目本质

这是一个带限制的图遍历问题,需要在一个二维地图上做路径搜索,且有如下特殊规则:


📌 规则总结

  1. 只能走四个方向:上、下、左、右;
  2. 不能走回头路:每个格子只能访问一次;
  3. 不能走等高路径
  4. 上坡下坡必须交替
    • 如果前一步是上坡(高度变高),下一步必须是下坡(高度变低);
    • 如果前一步是下坡,下一步必须是上坡;
    • 第一步可以任选上坡或下坡。

🔍 目标

求从任意起点出发,能连续移动的最大步数


🧠 解法思路:DFS + 回溯

用深度优先搜索(DFS)尝试从每个格子出发,走出最长的合法路径,结合回溯法控制访问标记。


🧱 状态定义

在 DFS 中维护的状态包括:

  • 当前坐标 (x, y)
  • 当前路径长度 steps
  • 当前移动方向 mode(1=上坡,-1=下坡,0=起点)

🔁 遍历逻辑

  • 从每一个起点 (i,j) 出发
  • 尝试四个方向走一步,看是否满足如下条件:
    • 不越界;
    • 没有访问过;
    • 高度不同;
    • 当前方向与前一步相反(即上坡后只能下坡,下坡后只能上坡);
### 华为OD机考 2025B 数字游戏 Java 编程题 解决方案 在华为OD机考 2025B中,数字游戏相关的编程题目通常涉及算法设计、数据结构应用以及逻辑推理。以下是一个可能的数字游戏问题及其解决方案。 #### 问题描述 假设有一个数字游戏,玩家需要从一个整数数组中选择若干个数字,使得这些数字的和等于目标值 `target`。要求输出所有可能的组合。如果不存在这样的组合,则返回空列表。 **输入:** - 一个整数数组 `nums`。 - 一个整数目标值 `target`。 **输出:** - 所有可能的组合列表,每个组合是一个子数组。 **示例:** ```plaintext 输入: nums = [2, 3, 6, 7], target = 7 输出: [[7], [2, 2, 3]] ``` #### 解决方案 以下是使用回溯法(Backtracking)解决该问题的 Java 实现: ```java import java.util.ArrayList; import java.util.List; public class NumberGame { public static List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> result = new ArrayList<>(); if (candidates == null || candidates.length == 0) return result; // 排序以优化剪枝 java.util.Arrays.sort(candidates); backtrack(result, new ArrayList<>(), candidates, target, 0); return result; } private static void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] candidates, int remain, int start) { if (remain < 0) return; // 超过目标值,直接返回 if (remain == 0) { // 找到一个组合 result.add(new ArrayList<>(tempList)); return; } for (int i = start; i < candidates.length; i++) { tempList.add(candidates[i]); backtrack(result, tempList, candidates, remain - candidates[i], i); // 不移动起点,允许重复使用 tempList.remove(tempList.size() - 1); // 回溯 } } public static void main(String[] args) { int[] nums = {2, 3, 6, 7}; int target = 7; List<List<Integer>> result = combinationSum(nums, target); System.out.println("结果: " + result); } } ``` #### 代码说明 1. **输入排序**:为了优化剪枝操作,首先对输入数组进行排序[^1]。 2. **回溯函数**:通过递归实现回溯,每次尝试将当前数字加入临时列表,并递归调用自身以寻找剩余目标值的组合。 3. **剪枝条件**:当剩余目标值小于 0 时,停止进一步递归;当剩余目标值等于 0 时,保存当前组合并返回。 4. **重复使用元素**:允许同一个数字被多次使用,因此递归调用时传入的起点索引不增加。 #### 时间复杂度与空间复杂度 - **时间复杂度**:最坏情况下为 \(O(2^n)\),其中 \(n\) 是数组长度,因为每个数字都有选或不选两种状态。 - **空间复杂度**:取决于递归深度,最坏情况下为 \(O(n)\)[^2]。 #### 测试结果 运行上述代码,对于输入 `nums = [2, 3, 6, 7]` 和 `target = 7`,输出结果为: ```plaintext 结果: [[2, 2, 3], [7]] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

算法大师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值