经过上一题农夫👨🌾和牛🐂的练习
附上上次的链接:[算法]BFS广度优先搜索(基础1)
下面我们来尝试一下走二维的迷宫
从左上角走迷宫到右下角:
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
其中1为障碍物,0为可通行
#include <bits/stdc++.h>
using namespace std;
#define MAP_SIZE 5
#define ERROR -1
#define OK 1
char tu[MAP_SIZE][MAP_SIZE] = {0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0};
bool vis[MAP_SIZE][MAP_SIZE];
struct node
{
int x;
int y;
int step;
};
queue<node>q;
struct point
{
int x;
int y;
};
point Last[MAP_SIZE][MAP_SIZE];
int OP[MAP_SIZE][MAP_SIZE];
void Push(node next, node now, int go_way)
{
if(next.x < 0 || next.x >= MAP_SIZE || next.y < 0 || next.y >= MAP_SIZE)
return ;
if(tu[next.x][next.y] == 0 && vis[next.x][next.y] == 0)
{
q.push(next);
vis[next.x][next.y] = 1;
point last;
last.x = now.x;
last.y = now.y;
Last[next.x][next.y] = last;
OP[next.x][next.y] = go_way;
}
}
int BFS(int x, int y)
{
if(tu[x][y] == 1) return ERROR;
node start;
start.x = x;
start.y = y;
start.step = 0;
while(!q.empty()) q.pop();
memset(vis, 0, sizeof(vis));
q.push(start);
vis[x][y] = 1;
while(!q.empty())
{
node now;
now = q.front();
q.pop();
/*退出条件*/
if(now.x == MAP_SIZE - 1 && now.y == MAP_SIZE - 1)
{
cout << "最少要" << now.step << "步才能走出迷宫" << endl;
cout << "步骤:";
stack<int>ans;
point path;
path.x = now.x;
path.y = now.y;
while(true)
{
ans.push(OP[path.x][path.y]);
path = Last[path.x][path.y];
if(path.x == start.x && path.y == start.y)
break;
}
while(!ans.empty())
{
if(ans.top() == 'D')
cout << 'D';
else if(ans.top() == 'R')
cout << 'R';
else if(ans.top() == 'L')
cout << 'L';
else if(ans.top() == 'U')
cout << 'U';
ans.pop();
}
return OK;
}
node next = now;
next.step = now.step + 1;
/*向下走*/
next.x = now.x+1;
next.y = now.y;
Push(next, now, 'D');
/*向右走*/
next.x = now.x;
next.y = now.y+1;
Push(next, now, 'R');
/*向上走*/
next.x = now.x-1;
next.y = now.y;
Push(next, now, 'U');
/*向左走*/
next.x = now.x;
next.y = now.y-1;
Push(next, now, 'L');
}
return ERROR;
}
int main()
{
if(BFS(0, 0) == -1)
cout << "无效的开始坐标或无解" << endl;
return 0;
}
/*
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
*/
上面有几个需要注意的地方:
1.由于在二维中,所以用结构体来存放人的坐标
2.由于在二维中,我们表示行走方式的数组OP存放的是"UDLR"分别代表上下左右
3.寻找路径的时候用到了栈,有先进后出的特点,符合我们的打印需求
4.输出的时候由于这个迷宫可能无解,所以要设置输出无解的条件(队列已经空了,但还没有碰到终点)