2025 A卷 200分 題型
本專欄內全部題目均提供Java、python、JavaScript、C、C++、GO六種語言的最佳實現方式;
并且每種語言均涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、3個測試用例以及綜合分析;
本文收錄于專欄:《2025華為OD真題目錄+全流程解析+備考攻略+經驗分享》
華為OD機試真題《智能駕駛》:
文章快捷目錄
題目描述及說明
Java
python
JavaScript
C
GO
題目名稱:智能駕駛
- 知識點:動態規劃、貪心算法、圖搜索(BFS/DFS)
- 時間限制:1秒
- 空間限制:256MB
- 限定語言:不限
題目描述
一輛汽車需要從 ( m \times n ) 的地圖左上角(起點)行駛到右下角(終點)。每個格子有以下屬性:
- -1:加油站,可加滿油(油箱容量最大為100)。
- 0:障礙物,無法通過。
- 正整數:通過該格子需消耗的油量。
規則:
- 汽車可上下左右移動。
- 初始油量需確保能到達終點,計算最少初始油量。若無法到達,返回-1。
- 油箱初始為空,若起點為加油站則初始油量為100。
輸入:
- 首行兩個整數 ( m ) 和 ( n ),表示地圖行數和列數。
- 接下來 ( m ) 行,每行 ( n ) 個整數,表示地圖數據。
輸出:
- 最少初始油量或-1。
示例:
輸入:
2 2
10 20
30 40
輸出:
70
解釋:路徑為右→下,初始油量需 ≥ 10(起點) + 30(下一步) = 40,但實際需覆蓋路徑最大累計消耗(10+20+40=70)。
Java
問題分析
汽車需要從地圖左上角移動到右下角,每個格子可能有不同的油量消耗或加油站。油箱容量最大為100,初始油量為空。若起點是加油站,初始油量為100。要求找到能到達終點的最小初始油量,若無法到達返回-1。
解題思路
- 動態規劃與優先隊列:使用Dijkstra算法,優先擴展當前最大油量消耗最小的路徑。
- 狀態定義:每個狀態包括當前位置、當前區段累計油量、路徑最大油量消耗。
- 加油站處理:到達加油站時,油量加滿,當前區段累計油量重置為0。
- 障礙物處理:遇到障礙物直接跳過。
代碼實現
import java.util.*;class State implements Comparable<State> {int i, j;int currentSegment;int maxSoFar;public State(int i, int j, int currentSegment, int maxSoFar) {this.i = i;this.j = j;this.currentSegment = currentSegment;this.maxSoFar = maxSoFar;}@Overridepublic int compareTo(State other) {return Integer.compare(this.maxSoFar, other.maxSoFar);}
}public class Main {private static String getKey(int i, int j, int segment) {return i + "," + j + "," + segment;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int m = scanner.nextInt();int n = scanner.nextInt();int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = scanner.nextInt();}}// 起點是障礙物if (grid[0][0] == 0) {System.out.println(-1);return;}PriorityQueue<State> pq = new PriorityQueue<>();Map<String, Integer> dist = new HashMap<>();// 初始化起點if (grid[0][0] == -1) {pq.offer(new State(0, 0, 0, 0));dist.put(getKey(0, 0, 0), 0);} else {int initialCost = grid[0][0];pq.offer(new State(0, 0, initialCost, initialCost));dist.put(getKey(0, 0, initialCost), initialCost);}int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};while (!pq.isEmpty()) {State state = pq.poll();int i = state.i;int j = state.j;int currentSegment = state.currentSegment;int maxSoFar = state.maxSoFar;// 到達終點if (i == m - 1 && j == n - 1) {System.out.println(maxSoFar);return;}String currentKey = getKey(i, j, currentSegment);if (dist.getOrDefault(currentKey, Integer.MAX_VALUE) < maxSoFar) {continue;}for (int[] dir : dirs) {int ni = i + dir[0];int nj = j + dir[1];if (ni < 0 || nj < 0 || ni >= m || nj >= n) continue;int cellValue = grid[ni][nj];if (cellValue == 0) continue;int cost = cellValue == -1 ? 0 : cellValue;int newSegment = currentSegment + cost;boolean isGasStation = cellValue == -1;int newMax = Math.max(maxSoFar, newSegment);// 處理加油站if (isGasStation) {if (newSegment > 100) continue;newSegment = 0; // 加滿油,新區段從0開始} else {// 來自加油站或起點是加油站,新區段不能超過100if (currentSegment == 0 && newSegment > 100) {continue;}}int newSegmentAfter = isGasStation ? 0 : newSegment;State newState = new State(ni, nj, newSegmentAfter, newMax);String newKey = getKey(ni, nj, newSegmentAfter);if (!dist.containsKey(newKey) || newMax < dist.getOrDefault(newKey, Integer.MAX_VALUE)) {dist.put(newKey, newMax);pq.offer(newState);}}}System.out.println(-1);}
}
代碼詳解
- State類:存儲當前位置、當前區段累計油量、路徑最大油量消耗,并實現優先隊列比較接口。
- 輸入處理:讀取地圖數據,處理起點障礙物情況。
- 優先隊列初始化:根據起點是否為加油站設置初始狀態。
- 狀態擴展:遍歷四個方向,計算新位置的油量消耗,處理加油站邏輯,更新狀態并加入優先隊列。
- 終點檢測:到達終點時輸出結果。
示例測試
示例1輸入:
2 2
10 20
30 40
輸出:70
示例2輸入:
3 3
-1 20 0
30 0 40
50 60 70
輸出:100
(路徑包含加油站,最大區段消耗為30+50=80,但需加滿油)
示例3輸入:
2 2
0 10
20 30
輸出:-1
(起點障礙物)
綜合分析
- 時間復雜度:使用優先隊列處理狀態,最壞情況O(N log N),適用于小規模地圖。
- 空間復雜度:存儲狀態信息,O(MNC),C為區段油量可能值。
- 正確性:通過Dijkstra算法保證找到最優路徑,處理加油站和障礙物邏輯。
- 適用性:適用于各種地圖配置,正確處理油量限制和加油站邏輯。
python
問題分析
汽車需要從地圖左上角移動到右下角,每個格子可能有不同的油量消耗或加油站。油箱容量最大為100,初始油量為空。若起點是加油站,初始油量為100。要求找到能到達終點的最小初始油量,若無法到達返回-1。
解題思路
- 優先隊列(Dijkstra算法):每次擴展當前最大油量消耗最小的路徑。
- 狀態定義:每個狀態包括位置、當前區段累計油量、路徑最大油量消耗。
- 加油站處理:到達加油站時,油量加滿,當前區段累計油量重置為0。
- 障礙物處理:遇到障礙物直接跳過。
代碼實現
import heapqdef min_initial_fuel(grid):m = len(grid)if m == 0:return -1n = len(grid[0])if grid[0][0] == 0:return -1 # 起點是障礙物start_val = grid[0][0]# 初始化起點狀態if start_val == -1:initial_segment = 0initial_max = 0else:if start_val > 100:return -1 # 初始油量不足initial_segment = start_valinitial_max = start_valheap = []heapq.heappush(heap, (initial_max, 0, 0, initial_segment))visited = {}visited_key = (0, 0, initial_segment)visited[visited_key] = initial_maxdirs = [(-1, 0), (1, 0), (0, -1), (0, 1)]while