广度优先搜索---迷宫问题(最短路径长度)

题目:

  给定一个 n x m大小的迷宫,其中 “*” 代表不可通过的墙壁,而 ’.‘代表平地,S表示起点,T表示终点。移动过程中,如果当前位置是(x,y)(下标从0开始),且每次只能往上下左右四个方向的平地移动,求从起点S到达终点T的最少步数

.....

.*.*.

.*S*.

.***.

...T*

在上面的样例中,S的坐标为(2,2),T的坐标为(4,3)。

输入格式:

 第一行给出m,n,表示迷宫的行,列;

 下面每一行给出 n个字符,共 m行;

最后一行给出起点坐标S1,S2,终点坐标T1,T2。

输出格式:

输出从起点S到达终点T的最少步数, 不存在输出 -1。

输入样例 1:

5 5 

.....

.*.*.

.*S*.

.***.

...T*

2 2 4 3

输出样例 1:

11

输入样例 2:

5 5

.....

.*.*.

.*S*.

.***.

...T.

2 2 4 3

输出样例 2:

9

输入样例 3:

5 5

.....

.....

..S..

.....

...T.

2 2 4 3

输出样例 3:

3

直接上代码。。。BFS总的来说,比写的DFS代码多一些,奈何时间复杂度好,并且有模板,不容易出现死循环!!!。

 1 #include<iostream>
 2 #include<queue>
 3 #include<unordered_map>
 4 using namespace std;
 5 
 6 const int maxn = 100,INF = 0x3fffffff;
 7 struct Node {
 8     int x,y;
 9     int layer = 0;//记录从起点S到达该位置的最少步数(层数) 
10 } node;
11 char maze[maxn][maxn];
12 int m,n,MIN = INF;
13 int S1,S2,T1,T2;
14 int X[] = {0,0,1,-1};//控制访问的四个方向,新技能 get !!!
15 int Y[] = {1,-1,0,0};
16 bool inque[maxn][maxn] = {false};//标记元素是否已经入队---这样不会改变矩阵原本的状态,新技能get !!!
17 bool judge(int i,int j) {
18     if(i < 0 || j < 0 || i>= m||j>= n || maze[i][j] == '*' || inque[i][j] == true)
19         return false;
20     return true;
21 }
22 void BFS(int i, int j) {
23     queue<Node> que;                     //定义队列
24     node.x = i,node.y = j,node.layer = 0;
25     que.push(node);                          //入队
26     inque[i][j] = true;                      //标记已经入队
27     while(!que.empty()) {                    //队列非空
28         Node top = que.front();              //取出队首元素
29         que.pop();                           //队首元素出队
30         if(top.x == T1 && top.y == T2) {     //如果能到达终点 T 
31             MIN = top.layer;
32             break;
33         }
34         for(int i = 0; i < 4; ++i) {         //访问相邻的四个元素
35             int nowI = top.x + X[i];
36             int nowJ = top.y + Y[i];
37             if(judge(nowI,nowJ)) {
38                 node.x = nowI,node.y = nowJ,node.layer = top.layer + 1;
39                 que.push(node);              //入队
40                 inque[nowI][nowJ] = true;    //标记已经入队
41             }
42         }
43     }
44 }
45 
46 int main() {
47     cin>>m>>n;
48     for(int i = 0; i < m; ++i) {             //初始化迷宫
49         for(int j = 0; j < n; ++j)
50             cin>>maze[i][j];
51     }
52     cin>>S1>>S2>>T1>>T2;                     //起点(S1,S2)和终点(T1,T2)
53     BFS(S1,S2);                   //广度优先搜索
54     cout<< (MIN <INF? MIN : -1);
55     return 0;
56 }

运行结果 1:

 

 运行结果 2:

 

运行结果 3:

 

posted @ 2020-02-27 20:50  tangq123  阅读(969)  评论(0编辑  收藏  举报