码迷,mamicode.com
首页 > 其他好文 > 详细

有关dfs、bfs解决迷宫问题的个人见解

时间:2019-08-18 11:56:02      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:示例   存在   its   print   tor   最短路径   image   题目   坐标   

可以使用BFS或者DFS方法解决的迷宫问题!

题目如下:

kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口。kotori只能上下左右四个方向移动。她想知道有多少出口是她能到达的,最近的出口离她有多远?

输入描述:

第一行为两个整数n和m,代表迷宫的行和列数 (1≤n,m≤30)

后面紧跟着n行长度为m的字符串来描述迷宫。‘k‘代表kotori开始的位置,‘.‘代表道路,‘*‘代表墙壁,‘e‘代表出口。保证输入合法。

输出描述:

若有出口可以抵达,则输出2个整数,第一个代表kotori可选择的出口的数量,第二个代表kotori到最近的出口的步数。(注意,kotori到达出口一定会离开迷宫)

若没有出口可以抵达,则输出-1。
示例1

输入

复制
6 8
e.*.*e.*
.**.*.*e
..*k**..
***.*.e*
.**.*.**
*......e

输出

复制
2 7

说明

可供选择坐标为[4,7]和[6,8],到kotori的距离分别是8和7步。


DFS解决如下:
 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 char map[100][100];
 5 int use[100][100];
 6 int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; //上下左右四个方向
 7 int minn = 999999999;
 8 
 9 int pan(int x,int y)
10 {
11     if(0 <= x && x <= 5 && 0 <= y && y <= 7 && (map[x][y] == . || map[x][y]==k)) return 1;
12     else return 0;
13 }
14 
15 void dfs(int x,int y,int step)
16 {
17     // 递归程序,必须要设置整个程序的出口,在dfs中,即当走到迷宫出口处即可结束程序
18     if(map[x][y] == e)
19     {
20         cout<<"success"<<endl;
21         if(step < minn) minn = step;
22         return;
23     }
24     for(int i = 0; i < 4; i++)
25     {
26         if(pan(x,y) && use[x][y] != 1) 
27         {
28             use[x][y] = 1;
29             cout<<"dd";
30             cout<<"  "<<map[x+dir[i][0]][y+dir[i][1]]<<endl;
31             dfs(x+dir[i][0],y+dir[i][1],step+1);
32             use[x][y] = 0;
33         }        
34     }
35 
36 }
37 int main()
38 {
39     int n;
40     int m;
41     cin >> n >> m;
42     // 4,5行已经定义了map和use数据,所以在此处不必int map[n][m],直接map[n][m]即可,否则报错 
43     map[n][m];
44     use[n][m];
45     memset(use,0,sizeof(use));
46     int x_start = 0;
47     int y_start = 0;
48     int step = 0;
49     for(int i = 0; i < n; i++)
50     {
51         for(int j = 0; j < m; j++)
52         {
53             cin >> map[i][j];
54             if(map[i][j] == k)
55             {
56                 x_start = i;
57                 y_start = j;
58             }
59         }
60     }
61     cout<<x_start<<" "<<y_start<<endl;
62     dfs(x_start, y_start, step);
63     cout<<"最小步数"<<minn<<endl;
64 } 

技术图片

 

 

 

BFS解决如下:

(1)自己写的有缺陷的代码:

 1 #include<iostream>
 2 #include<queue>
 3 #include<string.h>
 4 using namespace std;
 5 char map[100][100];
 6 int vis[100][100];
 7 int use[100][100];
 8 int m,n;
 9 int x_start,y_start;
10 queue<int> que;
11 int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
12 int cnt = 0;
13 int mi = 999999;
14 
15 int pan(int x,int y)
16 {
17     if(0 <= x && x <= n-1 && 0 <= y && y <= m -1 &&map[x][y] != *) return 1;
18     else return 0;
19 }
20 
21 void bfs(int x,int y)
22 {
23     int x1 = x;
24     int y1 = y;
25     while(!que.empty())
26     {
27         vis[x1][y1] = 1;
28         x1 = que.front();
29         que.pop();
30         y1 = que.front();
31         que.pop(); 
32         cout<<"x1:"<<x1<<" "<<"y1:"<<y1<<endl; 
33         if(map[x1][y1] == e)
34         {
35             if(use[x1][y1] == 0)
36             {
37                 cnt++;
38                 use[x1][y1]=1;
39             }
40             continue;
41         }
42 
43         for(int i = 0; i < 4; i++)
44         {
45             int xx = x1 + dir[i][0];
46             int yy = y1 + dir[i][1];
47             if(pan(xx,yy) && vis[xx][yy] == 0)
48             {
49                 cout<<"dd"<<endl;
50                 cout<<xx<<" "<<yy<<endl;
51                 que.push(xx);
52                 que.push(yy);
53                 vis[xx][yy] = 1;
54             }
55         }    
56     }    
57 }
58 
59 int main()
60 {
61     memset(vis,0,sizeof(vis));
62     memset(use,0,sizeof(use));
63     cin >> n >> m;
64     for(int i = 0; i < n; i++)
65     {
66         for(int j = 0; j < m; j++)
67         {
68             cin >> map[i][j];
69             if(map[i][j] == k)
70             {
71                 x_start = i;
72                 y_start = j;
73             }
74         }
75     }
76     que.push(x_start);
77     que.push(y_start);
78     bfs(x_start,y_start);
79     cout<<cnt<<endl;
80 
81 } 

对于每个点每个状态我采用的是直接利用队列记录他们的坐标值,而不是如AC代码一样利用结构体记录每个点的每个状态。所以导致我整个程序还是存在很大的缺陷,例如求最短路径的时候就比较困难。

所以对于BFS的题目,强烈建议把每个点每个状态先用结构体表示,然后利用队列记录这些结构体即可。

(2)AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char a[35][35];
 4 bool usd[35][35];
 5 int Move[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
 6 struct now
 7 {
 8     int x,y,dis;
 9 };
10 queue<now>q;
11 int main()
12 {
13     int n,m,cnt=0;
14     scanf("%d%d",&n,&m);
15     now s;
16     for(int i=1;i<=n;++i)
17         for(int j=1;j<=m;++j)
18         {
19             cin>>a[i][j];
20             if(a[i][j]==k)
21             {
22                 s.x=i;
23                 s.y=j;
24                 s.dis=0;
25             }
26         }
27     q.push(s);
28     int ans=99999999;
29     while(!q.empty())
30     {
31         now Now=q.front();
32         q.pop();
33         if(a[Now.x][Now.y]==e)
34         {
35             if(!usd[Now.x][Now.y])
36             {
37                 ++cnt;
38                 ans=min(ans,Now.dis);
39             }
40             usd[Now.x][Now.y]=true;
41             continue; //到达出口"e"处就必须跳过一下步骤,不能在对出口点“e”进行下面的扩展步骤(上下左右)
42         }
43         usd[Now.x][Now.y]=true;
44         for(int i=0;i<4;++i)
45         {
46             int xx=Now.x+Move[i][0],yy=Now.y+Move[i][1],d=Now.dis;
47             if(xx<=n&&xx>=1&&yy>=1&&yy<=m&&!usd[xx][yy]&&a[xx][yy]!=*)
48             {
49                 now t;
50                 t.x=xx;
51                 t.y=yy;
52                 t.dis=d+1;
53                 q.push(t);
54             }
55         }
56     }
57     if(!cnt)
58         return !printf("-1\n");
59     printf("%d %d\n",cnt,ans);
60     return 0;
61 }

技术图片

 带路径输出的BFS(路径的输出主要依靠递归程序,记录每个点的结构体还需要记录每个点的前驱节点的坐标)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char a[35][35];
 4 bool usd[35][35];
 5 int Move[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
 6 struct now
 7 {
 8     int x,y,dis,pre_x,pre_y;
 9 };
10 queue<now>q;
11 now buf[35];
12 int count1 = 0;
13 
14 void print(int x,int y)
15 {
16     int temp;
17     for(int i = 0; i < count1; i++)
18     {
19         if(buf[i].x == x && buf[i].y == y) temp = i;
20     }
21     if(x == -1 && y == -1) return;
22     else
23     {
24         print(buf[temp].pre_x,buf[temp].pre_y);
25         cout<<"("<<x<<","<<y<<")"<<endl;
26     }
27 }
28 
29 int main()
30 {
31     int n,m,cnt=0;
32     scanf("%d%d",&n,&m);
33     now s;
34     for(int i=1;i<=n;++i)
35         for(int j=1;j<=m;++j)
36         {
37             cin>>a[i][j];
38             if(a[i][j]==k)
39             {
40                 s.x=i;
41                 s.y=j;
42                 s.pre_x = -1;
43                 s.pre_y = -1;
44                 s.dis=0;
45             }
46         }
47     q.push(s);
48     int ans=99999999;
49     while(!q.empty())
50     {
51         now Now=q.front();
52         buf[count1++] = Now;
53         q.pop();
54         if(a[Now.x][Now.y]==e)
55         {
56             if(!usd[Now.x][Now.y])
57             {
58                 ++cnt;
59                 ans=min(ans,Now.dis);
60                 usd[Now.x][Now.y]=true;
61                 print(Now.x,Now.y);
62             }
63             continue;
64         }
65         usd[Now.x][Now.y]=true;
66         for(int i=0;i<4;++i)
67         {
68             int xx=Now.x+Move[i][0],yy=Now.y+Move[i][1],d=Now.dis;
69             if(xx<=n&&xx>=1&&yy>=1&&yy<=m&&!usd[xx][yy]&&a[xx][yy]!=*)
70             {
71                 now t;
72                 t.x=xx;
73                 t.y=yy;
74                 t.pre_x = Now.x;
75                 t.pre_y = Now.y;
76                 t.dis=d+1;
77                 q.push(t);
78             }
79         }
80     }
81     if(!cnt)
82         return !printf("-1\n");
83     printf("%d %d\n",cnt,ans);
84 //    for(int i = 0; i < count1; i++)
85 //    {
86 //        cout<<buf[i].x<<" "<<buf[i].y<<" "<<buf[i].pre_x<<" "<<buf[i].pre_y<<endl;
87 //    }
88     return 0;
89 }

 

有关dfs、bfs解决迷宫问题的个人见解

标签:示例   存在   its   print   tor   最短路径   image   题目   坐标   

原文地址:https://www.cnblogs.com/XDU-Lakers/p/11369260.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!