前言:迷宮問題很常見,若求最小路徑,一般用廣度優先搜索,主要要注意幾點:
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;
}