华为OD机试 2024D卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
小华和小为是很好的朋友,他们约定周末一起吃饭,通过手机交流,他们在地图上选择了很多聚餐地点 (由于自然地形等原因,部分聚餐地点不可达),求小华和小为都能达到的聚餐地点有多少个。
二、输入描述
第一行输入 m 和 n,m 表示地图长度,n 表示地图宽度
第二行开始具体输入地图信息,地图信息包括
0 为通畅的道路
1 为障碍物(且仅 1 为障碍物)
2 为小华或小为,地图中必定有且仅有两个(非障碍物)
3 为被选中的聚餐地点(非障碍物)
三、输出描述
可以两方都到达的聚餐地点的数量,行末无空格。
补充说明
地图长宽为m和n,4 <= m <= 100 ,4 <= n <= 100
聚餐的地点数量为k,则1 < k <= 100
四、解题思路
本题要求我们在一个二维地图上找到小华和小为都能到达的聚餐地点。我们可以通过广度优先搜索(BFS)从小华和小为的起始位置分别进行搜索,记录每个可达位置。最后统计两者都能到达的聚餐地点数量。
具体步骤如下:
- 读取输入:
- 读取地图的长宽 m 和 n。
- 读取地图信息,记录小华和小为的起始位置,以及聚餐地点的位置。
- 广度优先搜索(BFS):
- 从小华和小为的起始位置分别进行BFS,记录每个可达的位置。
- 使用一个布尔矩阵 visited1 记录小华能到达的位置,使用 visited2 记录小为能到达的位置。
- 统计结果:
- 遍历聚餐地点的位置,统计小华和小为都能到达的地点数量。
五、Java算法源码
public class Test01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取地图的长和宽
int m = scanner.nextInt();
int n = scanner.nextInt();
scanner.nextLine();
// 初始化地图
int[][] map = new int[m][n];
int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int[] start1 = new int[2];
int[] start2 = new int[2];
LinkedList<int[]> meetingPoints = new LinkedList<>();
int startIndex = 0;
// 读取地图信息
for (int i = 0; i < m; i++) {
String[] row = scanner.nextLine().split(" ");
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(row[j]);
if (map[i][j] == 2) {
// 记录小华和小为的起始位置
if (startIndex == 0) {
start1[0] = i;
start1[1] = j;
startIndex++;
} else {
start2[0] = i;
start2[1] = j;
}
} else if (map[i][j] == 3) {
// 记录聚餐地点
meetingPoints.add(new int[]{i, j});
}
}
}
scanner.close();
// 执行广度优先搜索(BFS),记录小华和小为分别能到达的地点
boolean[][] visited1 = bfs(map, start1, m, n, directions);
boolean[][] visited2 = bfs(map, start2, m, n, directions);
int commonPoints = 0;
// 统计小华和小为都能到达的聚餐地点数量
for (int[] point : meetingPoints) {
if (visited1[point[0]][point[1]] && visited2[point[0]][point[1]]) {
commonPoints++;
}
}
// 输出结果
System.out.println(commonPoints);
}
/**
* 广度优先搜索(BFS)函数,记录从起始位置能到达的所有位置
* @param map 地图矩阵
* @param start 起始位置
* @param m 地图的行数
* @param n 地图的列数
* @param directions 移动的四个方向
* @return 记录能到达的位置的布尔矩阵
*/
private static boolean[][] bfs(int[][] map, int[] start, int m, int n, int[][] directions) {
boolean[][] visited = new boolean[m][n]; // 记录访问过的位置
Queue<int[]> queue = new LinkedList<>();
queue.add(start);
visited[start[0]][start[1]] = true;
// 广度优先搜索
while (!queue.isEmpty()) {
int[] current = queue.poll();
for (int[] direction : directions) {
int newRow = current[0] + direction[0];
int newCol = current[1] + direction[1];
// 检查新位置是否在地图范围内,是否未访问过,且不是障碍物
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && !visited[newRow][newCol] && map[newRow][newCol] != 1) {
queue.add(new int[]{newRow, newCol});
visited[newRow][newCol] = true;
}
}
}
return visited;
}
}
六、效果展示
1、输入
4 4
2 1 0 3
0 1 2 1
0 3 0 0
0 0 0 0
2、输出
2
3、说明
第一行输入地图的长宽为4和4
第二行开始为具体的地图,其中:
3 代表小华和小明的聚餐地点;
2 代表小华或小明(确保有2个);
0 代表可以通行的位置;
1 代表不可以出行的位置。
此时2者都能达到的聚餐位置有两处
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 C卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。