知识点 BFS + 记录路径
2021/1/28
题面来找到~~
定义一个二维数组:
int maze[5][5] = {
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表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
--------------------------------------------分割线-------------------------------------------------------------
首先给出 AC 代码: 新手理解在后面!
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
char mp[10][10];
int x[4] = {0,1,0,-1};
int y[4] = {1,0,-1,0};
bool sg[6][6];
struct pt
{
int x,y;
int pre;
}now,tp,ans[100];
queue<pt> q;
void print(pt q)
{
while(q.pre != -1)
{
print(ans[q.pre]);
cout << "(" << q.x << ","<<" "<<q.y<< ")" << endl;
return ;
}
cout << "(" << 0 << ","<<" "<< 0 << ")" << endl;
}
void bfs()
{
int f = 0,end = 0;
memset(sg,false,sizeof(sg));
pt r;
r.x = 0;
r.y = 0;
r.pre = -1;
q.push(r);
end++;
ans[0] = r;
while(!q.empty())
{
now = q.front();
q.pop();
if(now.x == 4 && now.y == 4)
{
print(now);
return ;
}
for(int i = 0; i < 4; i++)
{
int nx = now.x + x[i];
int ny = now.y + y[i];
if(nx < 0 || nx >= 5 || ny < 0 || ny >= 5) continue;
if(mp[nx][ny] == '1' || sg[nx][ny]) continue;
sg[nx][ny] = true;
tp.x = nx;
tp.y = ny;
tp.pre = f;
q.push(tp);
ans[end++] = tp;
}
f++;
}
}
int main()
{
for(int i = 0; i < 5; i++)
for(int j = 0; j < 5; j++)
cin >> mp[i][j];
bfs();
return 0;
}
反思:
1.抛去记录路径这是一道BFS的模板题,没什么好说的;
2.如何记录路径呢?
先用数组记录路径,然后递归打印路径,具体操作如下
// 使用的结构体
struct pt // point
{
int x,y;
int pre; // 用来记录该点的前一个点;意思说使用数来表示一个点。。
}now,tp,ans[100]; // 结构体数组是用来访问点的!
tp.pre = f; // 用来存储该点上一个点的数,以用于后面访问改点的内容
ans[end++] = tp; // 在数组中存入该点信息;
//找到最短路径后,递归打印路径
void print(pt q)
{
while(q.pre != -1)
{
print(ans[q.pre]);
cout << "(" << q.x << ","<<" "<<q.y<< ")" << endl;
return ;
}
cout << "(" << 0 << ","<<" "<< 0 << ")" << endl;
}
根据Sample Input 来模拟该过程:
红色代表 f 在该点的值,粉色代表 end 在该点的值,同时由
tp.pre = f; // 用来存储该点上一个点的数,以用于后面访问改点的内容
ans[end++] = tp; // 在数组中存入该点信息;
end 就是 用来访问该点信息的:
因为是递归,会从终点直接递归到起点,如何找到前一个点,看图!
终点的 f 是13 即 终点 pre = 13; 那好
print(ans[q.pre])
ans【13】 的内容就是 终点的上一个点的 结构体!上一个点的结构体里存的pre = 10,则ans【10】 的内容就是它上一个点的结构体!!! 这样一直递归到 起点的前一个点 后面开始回溯;
如果了解数组模拟队列的话,更好理解!!
建议过程去模拟一次,不要怕花时间!!
考虑不周之处希望能够指出!