dfs解决迷宫问题(找步数)
dfs为深度优先搜索,即为顺着一条道走到黑,当什么时候走不动了,才开始往回开始走,它与bfs则不同,bfs是边走边看,把每种可能都看一下,但是dfs只要找到一条道路即可。话不多说了,直接看题把
问题描述:
小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。
小明只能向上下左右四个方向移动。
小明只能向上下左右四个方向移动。
输入
输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。
每组输入的第一行是两个整数N和M(1<=N,M<=100)。
接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。
字符的含义如下:
‘S’:起点
‘E’:终点
‘-’:空地,可以通过
‘#’:障碍,无法通过
输入数据保证有且仅有一个起点和终点。
每组输入的第一行是两个整数N和M(1<=N,M<=100)。
接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。
字符的含义如下:
‘S’:起点
‘E’:终点
‘-’:空地,可以通过
‘#’:障碍,无法通过
输入数据保证有且仅有一个起点和终点。
输出
对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。
样例输入
1
5 5
S-###
-----
##---
E#---
---##
样例输出
9
下面我来分别介绍一下bfs和dfs来解决问题得思路:
1、bfs迷宫问题在我得前一篇已经详细讲解了,若是没有看的话,请先去看,看完之后你会感觉豁然开朗。下面我就直接放bfs的代码了:
1 #include <stdio.h> 2 3 typedef struct ss 4 { 5 int x, y; 6 int pre; 7 }ss; 8 ss queue[100]; 9 int sx,sy,dx,dy; 10 int visit[100][100]={0}; 11 int dxy[4][2]={ 12 {-1,0}, 13 {0,1}, 14 {1,0}, 15 {0,-1} 16 }; 17 int a,b,step; 18 int array[100][100]; 19 void dfs(int x,int y); 20 void print_data(int rear); 21 int main(int argc, char *argv[]) 22 { 23 24 scanf("%d %d",&a,&b); 25 //printf("%d-%d-",a,b); 26 char st[a][b]; 27 28 int i,j; 29 for(i=0;i<a;i++) 30 { 31 getchar(); 32 for(j=0;j<b;j++) 33 { 34 scanf("%c",&st[i][j]); 35 if(st[i][j]=='S') 36 { 37 sx=i; 38 sy=j; 39 array[i][j]=0; 40 } 41 else if(st[i][j]=='E') 42 { 43 dx=i; 44 dy=j; 45 array[i][j]=0; 46 } 47 else if(st[i][j]=='-') 48 array[i][j]=0; 49 else if(st[i][j]=='#') 50 array[i][j]=1; 51 } 52 53 } 54 55 //printf("dx=%d,dy=%d\n",dx,dy); 56 57 for(i=0;i<a;i++) 58 { 59 for(j=0;j<b;j++) 60 printf("%d\t",array[i][j]); 61 printf("\n"); 62 } 63 dfs(sx,sy); 64 printf("%d%",step-1); 65 return 0; 66 } 67 68 void dfs(int x,int y) 69 { 70 int i,j; 71 int front=0,rear=1; 72 int next_x,next_y; 73 queue[front].x=x; 74 queue[front].y=y; 75 queue[front].pre=-1; 76 visit[x][y]=1; 77 78 while(front<rear) 79 { 80 for(i=0;i<4;i++) 81 { 82 next_x=queue[front].x+dxy[i][0]; 83 next_y=queue[front].y+dxy[i][1]; 84 if(next_x>=0&&next_x<a&&next_y>=0&&next_y<b&&array[next_x][next_y]==0&&visit[next_x][next_y]==0) 85 { 86 queue[rear].x=next_x; 87 queue[rear].y=next_y; 88 queue[rear].pre=front; 89 rear++; 90 visit[next_x][next_y]=1; 91 //printf("(%d %d)-%d-%d\n",next_x,next_y,front,rear); 92 } 93 94 if(next_x==dx&&next_y==dy) 95 print_data(rear-1); 96 } 97 front++; 98 } 99 } 100 101 void print_data(int rear) 102 { 103 if(rear!=-1) 104 { 105 106 print_data(queue[rear].pre); 107 108 printf("(%d %d)\n",queue[rear].x,queue[rear].y); 109 step++; 110 } 111 112 113 }
2、dfs去找步数真的是非常的方便啊,下面直接在代码上注释,代码如下:
1 #include <stdio.h> 2 #define max 0xffff 3 #define maxline 100 4 int sx,sy,dx,dy; //sx用来接收起点的x坐标,sy用来接收起点的y坐标;dx是用来接收终点的x坐标,dy是用来接收终点的y坐标 5 int a,b; //a,b分别是你要输入的迷宫的宽度和长度 6 int dis[maxline][maxline]; //定义一个距离数组,用来存放距离 7 int dxy[4][2]={ 8 {-1,0}, 9 {0,1}, 10 {1,0}, 11 {0,-1} 12 }; //用来改变方向的 13 14 void dfs(int sx,int sy,int step); 15 bool cmp(int next_x,int next_y,int step); 16 int main(int argc, char *argv[]) 17 { 18 char ch; 19 int i,j; 20 scanf("%d %d",&a,&b); 21 22 for(i=0;i<a;i++) 23 { 24 getchar(); 25 for(j=0;j<b;j++) 26 { 27 scanf("%c",&ch); 28 if(ch=='S') 29 { 30 sx=i; 31 sy=j; 32 dis[i][j]=0; 33 } 34 else if(ch=='E') 35 { 36 dx=i; 37 dy=j; 38 dis[i][j]=max; 39 } 40 else if(ch=='-') 41 dis[i][j]=max; 42 else 43 dis[i][j]=0; 44 } 45 } //接收数据,并且把可以通过的距离设置为最大值,不可通过的距离设置为0 46 47 for(i=0;i<a;i++) 48 { 49 for(j=0;j<b;j++) 50 printf("%d\t",dis[i][j]); 51 printf("\n"); 52 } //打印出我们设置的距离 53 54 dfs(sx,sy,0); //将起点和当前步数传入到dfs 55 printf("%d",dis[dx][dy]==max?-1:dis[dx][dy]); 56 return 0; 57 } 58 59 void dfs(int sx,int sy,int step) 60 { 61 int next_x, next_y; 62 int i; 63 for(i=0;i<4;i++) 64 { 65 next_x=sx+dxy[i][0]; //next_x是当前位置的下一步的x坐标 66 next_y=sy+dxy[i][1]; //next_y是当前文职的下一步的y坐标 67 if(cmp(next_x,next_y,step)) //判断next_x 、next_y是否合法 68 { 69 dis[next_x][next_y]=step+1; //若合法的话就将从起点到该点的距离存储到dis中 70 dfs(next_x,next_y,step+1); //然后从下一点开始dfs 71 } 72 } 73 } 74 75 bool cmp(int next_x,int next_y,int step) 76 { 77 if(next_x>=0&&next_x<a&&next_y>=0&&next_y<b&&step+1<dis[next_x][next_y]) 78 return true; 79 else 80 return false; 81 }
代码非常的简单,如果有什么不懂得可以在下方评论出你得疑惑;如果这篇文章对你有帮助得话,欢迎帮忙点个赞;如果你有更好的办法的话欢迎评论在下方,大家可以进行一起讨论,谢谢。
                    
                
                
            
        
浙公网安备 33010602011771号