dfs迷宫营救问题
程序员文章站
2022-07-13 11:19:44
...
搜索——深度优先算法(dfs)
有一天,小哈一个人去玩迷宫。凡是方向感不好的小哈很快迷路了。
小啊得知后便去解救无助的小哈。小啊当然是有备而来,已经弄清楚了迷宫的地图,现在小啊要以最快的速度去解救小哈
迷宫由m行n列组成(m,n>=50)
迷宫由空地和墙组成,0代表空地,1代表墙。
任务是找出一条小啊营救小哈的最短路径。
import java.util.Random;
import java.util.Scanner;
/**
* @author sjf
* @date 2020/3/2 21:58
*/
public class dfs_manRescuewoman {
static int endx, endy; //小啊的位置坐标
static int min=999999; //需要走的步数
static int[][] next = {{-1,0}/*上*/ ,{0,-1}/*左*/,{1,0}/*下*/,{0,1}/*右*/}; //方向数组,利于跑图
static int n,m; //迷宫为 n行m列
static int [][] map = new int[51][51]; //地图
static int [][] book = new int[51][51]; //标记数组
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
for (int i = 0; i <n; i++) {
for (int j = 0; j <m; j++) {
map[i][j] = new Random().nextInt(2); //输入地图
System.out.print(map[i][j]+" ");
}
System.out.println();
}
//小啊的起始坐标
int startx = sc.nextInt();
int starty = sc.nextInt();
//小哈的坐标
endx =sc.nextInt();
endy =sc.nextInt();
//从起点开始搜索
book[startx][starty] = 1;
dfs(startx,starty,0);
//输出
if(min!=999999)
System.out.println(min);
else
System.out.println("设置错标出错!!!/\n不可能完成营救任务!!!");
}
public static void dfs(int x ,int y ,int step){
int tx,ty;
//出口 即是 小啊 找到 小哈
if(x== endx &&y== endy){
//更新最小值
if(step<min){
min = step;
}
return;
}
//要做的是 上左下右 的走 相当于 放 卡牌到盒子里 这是我要做的
for (int i = 0;i<4;i++){
//尝试每一种走法
tx = x +next[i][0];
ty = y +next[i][1];
//判断是否越界
if(tx<0 || tx>n-1 || ty<0 || ty>m-1){
continue; //越过此次
}
//判断该点是否为 障碍物 且 是否走过
if(map[tx][ty]==0 && book[tx][ty]==0){
book[tx][ty] = 1; //标记这个点走过了
dfs(tx,ty,step+1); //往下一步走
book[tx][ty] = 0; //取消标记
}
}
return;
}
}
深度优先搜索:建立于递归回溯之上,其实就是遍历搜索树,每次失败导致回溯然后把做过的痕迹抹去,不断的去尝试,直至达到返回条件。
理解深度优先搜索的关键在于解决“当下该怎么做?”。至于“下一步如何做”“则与当下应该怎么做”是一样的。
void dfs(int step){
判断边界
尝试每一种可能 for(){
继续下一步 dfs(step+1);
}
返回
}
深度优先搜索对于迷宫跑图问题,不容易解决的问题就是设计出来一条路线
比如图片中的路线为:
DLLDLDLDDDDRRRDRRURRRDRRUUUR
(其中 D、U、L、R 分别表示向下、向上、向左、向右走)
广度优先搜索可以很好地解决此问题。
其实深度优先搜索同样简便可以规划处路线
利用 StringBuffer 随意增删
static StringBuffer ans = new StringBuffer(); //存储路径
public static void dfs(int x , int y ,int step){
int tx,ty;
//出口
if(x==n-1&&y==m-1){
System.out.println(step);
System.out.println(ans);
return;
}
//尝试每种选择
for (int i = 0; i < 4; i++) {
tx = x+next[i][0];
ty = y+next[i][1];
if(tx<0 || tx>n-1 || ty<0 || ty>m-1)
continue; //越过这步走法!
if(map[tx][ty]==0&&book[tx][ty]==0){
if(i==0)
ans.append("U");
if(i==1)
ans.append("L");
if(i==2)
ans.append("D");
if(i==3)
ans.append("R");
book[tx][ty] = 1; //记录
dfs(tx,ty,step+1); //回溯
book[tx][ty] = 0; //取消标记
ans.deleteCharAt(ans.length()-1);
}
}
return;
}
上一篇: 【洛谷 P1363】幻想迷宫(搜索)
下一篇: BFS & DFS 迷宫