dfs解决迷宫问题(找步数)

dfs为深度优先搜索,即为顺着一条道走到黑,当什么时候走不动了,才开始往回开始走,它与bfs则不同,bfs是边走边看,把每种可能都看一下,但是dfs只要找到一条道路即可。话不多说了,直接看题把

问题描述:

小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。
小明只能向上下左右四个方向移动。
输入
输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。
每组输入的第一行是两个整数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 }

代码非常的简单,如果有什么不懂得可以在下方评论出你得疑惑;如果这篇文章对你有帮助得话,欢迎帮忙点个赞;如果你有更好的办法的话欢迎评论在下方,大家可以进行一起讨论,谢谢。



posted @ 2021-07-21 14:16  快乐的余开心  阅读(239)  评论(0)    收藏  举报
!--点击火花特效-->