0.題目
1.題解
1.1 BFS搜尋
思路
這裡為何使用BFS搜尋呢?由於我們求得是最短路徑,BFS廣度優先多種情況齊頭並進,必然有一種情況最先到達終止條件,這時我們直接終止搜尋即可,不像DFS深度搜尋一種情況不對還要進行回溯,造成大量重複計算.
這裡使用BFS搜尋,我們依舊要考慮終止條件,邊界條件,以及構建BFS搜尋.
1.終止條件(check函式):到達終點(x2,y2); 如果BFS搜尋結束(while迴圈結束)還沒有找到,就輸出-1
2.邊界條件(pd函式): 不可超出邊界,不可重複走,不可走有障礙的路徑
3.BFS搜尋:
3.1 初始化
3.2 外層while迴圈
3.3 內層使用簡單圖論+for訓話,表示向四周移動; 使用佇列實現BFS搜尋
3.4 使用vis陣列記錄到達當前位置步數. 1.不會重複,pd函式中有專門判斷 2.一定是最小,由於是BFS搜尋,肯定是先記錄到較小步數,之後其他較大步數不會記錄
注意:
1.這裡我使用x1,y1,x2,y2作為初始座標,發生了報錯:mathcalls.h 中已經定義了 double y1(double),後改為使用pair對直接表示
2.不要使用map關鍵字作為識別符號!!!
程式碼
#include<bits/stdc++.h>
using namespace std;
int n, m;
int Map[101][101];
int vis[101][101] = {0};
pair<int, int> Start, End;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
// 路徑檢測
bool pd(int x, int y) {
// 超出邊界
if(x < 1 || x > n || y < 1 || y > m) {
return false;
}
// 已經走過了
if(vis[x][y] >= 1) {
return false;
}
// 不是路徑不能走
if(Map[x][y] != 1) {
return false;
}
return true;
}
// 終點檢測
bool check(int x, int y) {
if(x == End.first && y == End.second) {
cout << vis[x][y];
return true;
}
return false;
}
void BFS() {
// 初始化
queue<pair<int, int>> q;
q.push(make_pair(Start.first, Start.second));
// vis[x1][y1] = 1;
// BFS總迴圈
while(!q.empty()) {
pair<int, int> tempNode = q.front();
int x = tempNode.first;
int y = tempNode.second;
q.pop();
// 進行BFS擴充套件
for(int i = 0; i < 4; i++) {
int newX = x + dx[i];
int newY = y + dy[i];
// 透過路徑檢測
if(pd(newX, newY)) {
// 更新vis值
vis[newX][newY] = vis[x][y] + 1;
// 進行結果檢測
if(check(newX, newY)) {
exit(0);
}
// 不是最終點,更新佇列
q.push(make_pair(newX, newY));
}
}
}
cout << -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> Map[i][j];
}
}
cin >> Start.first >> Start.second >> End.first >> End.second;
BFS();
}