前言
经过前期的数据结构和算法学习,开始以OD机考题作为练习题,继续加强下熟练程度。有需要的可以同步练习下。迷宫问题是一个经典的路径搜索问题,通常可以用深度优先搜索(DFS)或广度优先搜索(BFS)来解决。
描述
定义一个二维数组 N*M ,如 5 × 5 数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
数据范围: 2≤𝑛,𝑚≤10 2≤n,m≤10 , 输入的内容只包含 0≤𝑣𝑎𝑙≤1 0≤val≤1
输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
示例1
输入:
5 5 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0输出:
(0,0) (1,0) (2,0) (2,1) (2,2) (2,3) (2,4) (3,4) (4,4)
实现原理
使用深度优先搜索(DFS)来遍历迷宫,从起点开始,尝试向四个方向(上、下、左、右)移动,直到找到终点或无法继续移动为止。
- 输入迷宫和起终点坐标:传入迷宫矩阵和起点、终点的坐标。
- 初始化路径列表:创建一个列表来保存路径。
- DFS搜索路径:使用递归的DFS方法从起点开始搜索路径,如果找到终点,返回true并记录路径;否则,返回false并回溯。
- 主函数调用:在主函数中调用 dfs 方法,并输出路径或提示没有路径。
实现代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int M = in.nextInt();
List<int[]> paths = new ArrayList();
int[][] maze = new int[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
maze[i][j] = in.nextInt();
}
}
dfs(maze,0, 0, N-1, M-1, paths);
for (int[] path : paths) {
System.out.println("("+path[0]+","+path[1]+")");
}
}
public static boolean dfs(int[][] maze,int x, int y, int endx, int endy,
List<int[]> paths) {
if (x < 0 || y < 0 || x > endx || y > endy||maze[x][y]==1) {
return false;
}
//路径记录
paths.add(new int[]{x,y});
//标记访问
maze[x][y]=1;
if(x==endx&&y==endy){
return true;
}
int[] dpx = {-1, 1, 0, 0};
int[] dpy = {0, 0, -1, 1};
//尝试4个方向
for(int i=0;i<4;i++){
int newX=x+dpx[i];
int newY=y+dpy[i];
if(dfs(maze,newX,newY,endx,endy,paths)){
return true;
}
}
//回溯
paths.remove(paths.size()-1);
maze[x][y]=0;
return false;
}
}