当解析这个问题时,按照以下步骤思考和处理:
1. 首先,读取输入数据,包括迷宫的行数和列数 `n` 和 `m`,起点坐标 `a` 和 `b`,终点坐标 `c` 和 `d`,以及迷宫的布局。
2. 然后,使用一个二维数组 `grid` 来表示迷宫,其中 `grid[i][j]` 的值为 0 表示该位置可以走,值为 1 表示该位置不可走。
3. 接下来,使用广度优先搜索(BFS)算法来找到从起点到终点的最短步数。
4. 使用一个二维数组 `visited` 来记录每个位置是否被访问过,初始值都为 `false`。
5. 使用一个二维数组 `steps` 来记录从起点到每个位置的步数,初始值都为 0。
6. 使用一个队列来存储待访问的位置,初始时将起点加入队列。
7. 在 BFS 的循环中,从队列中取出一个位置,并检查它的上、下、左、右四个相邻位置。如果相邻位置满足以下条件,则将其加入队列:
- 位置在迷宫范围内;
- 位置是可走的;
- 位置未被访问过。
8. 在加入队列时,更新 `visited` 和 `steps` 数组,并将当前位置的步数加 1。
9. 如果循环中找到了终点位置,即当前位置的行列坐标与终点坐标相同,则返回该位置的步数。
10. 如果循环结束时仍然没有找到终点位置,则返回 -1,表示无法到达终点。
11. 最后,输出最少需要的步数。
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // 迷宫的行数
int m = scanner.nextInt(); // 迷宫的列数
int a = scanner.nextInt(); // 起点的行坐标
int b = scanner.nextInt(); // 起点的列坐标
int c = scanner.nextInt(); // 终点的行坐标
int d = scanner.nextInt(); // 终点的列坐标
int[][] grid = new int[n][m]; // 迷宫的布局
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
grid[i][j] = scanner.nextInt();
}
}
int minSteps = -1; // 最少需要的步数,默认为-1
boolean[][] visited = new boolean[n][m]; // 记录位置是否被访问过
int[][] steps = new int[n][m]; // 记录从起点到每个位置的步数
Queue<int[]> queue = new LinkedList<>(); // 存储待访问的位置
queue.offer(new int[]{a, b}); // 将起点加入队列
visited[a][b] = true;
steps[a][b] = 0;
int[] dx = {-1, 1, 0, 0}; // 上下左右移动的行增量
int[] dy = {0, 0, -1, 1}; // 上下左右移动的列增量
while (!queue.isEmpty()) {
int[] curr = queue.poll();
int currRow = curr[0];
int currCol = curr[1];
if (currRow == c && currCol == d) { // 如果当前位置是终点,则找到最小步数,结束循环
minSteps = steps[currRow][currCol];
break;
}
for (int i = 0; i < 4; i++) {
int newRow = currRow + dx[i];
int newCol = currCol + dy[i];
if (newRow >= 0 && newRow < n && newCol >= 0 && newCol < m && grid[newRow][newCol] == 0 && !visited[newRow][newCol]) {
queue.offer(new int[]{newRow, newCol});
visited[newRow][newCol] = true;
steps[newRow][newCol] = steps[currRow][currCol] + 1;
}
}
}
System.out.println(minSteps); // 输出最少需要的步数
}
}