leetcode之迷宮問題---BFS 廣度優先搜索

 前言:迷宮問題很常見,若求最小路徑,一般用廣度優先搜索,主要要注意幾點:

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;
}   

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章