华为OD机试真题——战场索敌(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《战场索敌》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C
GO
题目名称:战场索敌
知识点:深度优先搜索(DFS)、广度优先搜索(BFS)、逻辑处理
时间限制:1秒
空间限制:256MB
限定语言:不限
题目描述
有一个大小为N×M的战场地图,被墙壁 #
分隔成不同的区域。上下左右四个方向相邻的空地 .
属于同一区域,只有空地上可能存在敌人 E
。要求统计地图中敌人数小于K的区域数量。
输入描述
- 第一行输入三个整数N、M、K,分别表示地图的行数、列数和目标敌人数阈值(N, M ≤ 100)。
- 接下来输入一个N×M的字符数组,表示战场地图,包含字符
#
(墙壁)、.
(空地)、E
(敌人)。
输出描述
- 输出一个整数,表示敌人数小于K的区域数量。
示例
输入:
3 5 2
..#EE
E.#E.
###..
输出:
1
说明
- 地图被墙壁分为两个区域:左侧区域有1个敌人,右侧区域有3个敌人,仅左侧区域满足条件。
输入约束
- 输入保证每个区域的敌人数量为非负整数。
- 任意两个敌人位置不重叠。
Java
问题分析
题目要求统计战场地图中被墙壁分隔的各个区域中,敌人数小于给定阈值的区域数量。每个区域由上下左右相邻的空地(包括敌人所在位置)组成,我们需要遍历每个区域并统计其中的敌人数。
解题思路
- 输入处理:读取地图的行数、列数和阈值K,然后读取地图数据。
- 遍历地图:使用双重循环遍历每个地图位置。
- 区域标记与统计:对于每个未被访问且非墙壁的位置,使用广度优先搜索(BFS)遍历整个区域,统计区域内的敌人数量。
- 判断条件:如果当前区域的敌人数小于K,则计入结果。
- 输出结果:统计符合条件的区域数量并输出。
代码实现
import java.util.Scanner;
import java.util.Queue;
import java.util.LinkedList;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 读取输入参数 N, M, Kint N = scanner.nextInt();int M = scanner.nextInt();int K = scanner.nextInt();scanner.nextLine(); // 跳过换行符// 读取战场地图数据char[][] grid = new char[N][M];for (int i = 0; i < N; i++) {String line = scanner.nextLine().trim();for (int j = 0; j < M; j++) {grid[i][j] = line.charAt(j);}}// 标记数组,记录每个位置是否被访问过boolean[][] visited = new boolean[N][M];int count = 0; // 符合条件的区域数量// 方向数组,用于BFS遍历四个方向int[] dx = {-1, 1, 0, 0};int[] dy = {0, 0, -1, 1};// 遍历地图中的每个位置for (int i = 0; i < N; i++) {for (int j = 0; j < M; j++) {// 如果当前位置是墙壁或已被访问,跳过if (grid[i][j] == '#' || visited[i][j]) {continue;}// BFS初始化Queue<int[]> queue = new LinkedList<>();queue.offer(new int[]{i, j});visited[i][j] = true;int cnt = 0; // 当前区域的敌人数// 如果当前起始位置是敌人,计数加1if (grid[i][j] == 'E') {cnt++;}// BFS遍历while (!queue.isEmpty()) {int[] curr = queue.poll();int x = curr[0];int y = curr[1];// 遍历四个方向for (int k = 0; k < 4; k++) {int nx = x + dx[k];int ny = y + dy[k];// 检查新位置是否合法且未被访问,且不是墙壁if (nx >= 0 && nx < N && ny >= 0 && ny < M && !visited[nx][ny] && grid[nx][ny] != '#') {visited[nx][ny] = true;// 如果是敌人,计数加1if (grid[nx][ny] == 'E') {cnt++;}queue.offer(new int[]{nx, ny});}}}// 判断当前区域的敌人数是否小于Kif (cnt < K) {count++;}}}// 输出结果System.out.println(count)