前言:迷宫问题很常见,若求最小路径,一般用广度优先搜索,主要要注意几点:
1)对新加四个方向符合要求的位置到队列时,判断是否被访问过,INF代表未被访问
d[nx][ny] == INF
2)到达终点的最小距离的表达式
d[nx][ny] = d[p.first][p.second] + 1;
3)存新的位置position(x,y)的定义,用pair不用map
typedef pair<int, int> position;
4)新的四个方向的位置的定义
int dx[4] = {1, 0,-1, 0}; // 左右方向
int dy[4] = {0, 1, 0, -1}; // 上下方向
for (i = 0; i < 4; i++) { // 新的位置的定义
int nx = p.first + dx[i];
int ny = p.second + dy[i];
...
}
题目:
/*
* 对于每个输入文件,第一行输入一个整数N(1<=N<=500),接下来N行,每行N个字符,表示这个迷宫的状态.
* 其中’S’表示小华的位置,’E’表示终点,’#’表示障碍物,’.’表示可以走的地方.
* Input: 3
#S#
...
E##
Output: 3
思路:
1.从起点开始,先将其加入队列,设置距离为0;
2.从队列首端取出位置,将从这个位置能够到达的四个方向的位置加入队列,并且让这些位置的距离为上一个位置的距离加上1;
3.循环2直到将终点添加到队列中,这说明我们已经找到了路径;
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
char INF = 0x3f3f3f3f; // 初始化时,队列存新的位置position(x,y)的值都为INF,对待放入队列的位置进行判断是否访问过
int d[3][3] = {0}; // 这里的值是可变的,由输入决定
typedef pair<int, int> position; // 存新的位置position(x,y)
void BFS(vector<vector<char>> &matrix, int x, int y, int Ex, int Ey) {
if ((x < 0) || (y < 0) || (x >= matrix.size()) || (y >= matrix[0].size()) || matrix[x][y] == '#') {
return;
}
queue<position> q;
q.push(position(x, y));
d[x][y] = 0; // 从起点出发将距离设为0,并放入队列首端
int dx[4] = {1, 0,-1, 0}; // 左右方向
int dy[4] = {0, 1, 0, -1}; // 上下方向
int i;
int index = 4;
while (!q.empty()) {
auto p = q.front();
q.pop();
for (i = 0; i < 4; i++) {
int nx = p.first + dx[i];
int ny = p.second + dy[i];
if (nx >= 0 && nx < matrix.size() && matrix[nx][ny] != '#' && d[nx][ny] == INF) { // 如果四个新的方向都没访问过
q.push(position(nx, ny)); // 往队列中插入新的四个方向
d[nx][ny] = d[p.first][p.second] + 1; // 距离加1
}
if (nx == Ex && ny == Ey) { // 如果到了终点,跳出循环,不再往队列中插入新的四个方向的位置
break;
}
}
if (i != index) { break; }
}
}
int main()
{
vector<vector<char>> matrix = {{'#', 'S', '#'},{'.', '.', '.'},{'E', '#', '#'}};
int startX, startY, endX, endY;
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[0].size(); j++) {
d[i][j] = INF;
if (matrix[i][j] == 'S') {
startX = i;
startY = j;
}
if (matrix[i][j] == 'E') {
endX = i;
endY = j;
}
}
}
BFS(matrix, startX, startY, endX, endY); // 广度优先搜索
cout << d[endX][endY] << endl; // 寻找到底终点的最短路径
return 0;
}