《演算法筆記》——BFS-迷宮最短路問題
阿新 • • 發佈:2018-12-18
題目大意:給定一個大小為N*M的迷宮。迷宮由通道(.)和牆壁(#)組成,每一步可以向鄰接的上下左右四個通道方向移動。求出從起點(S)到終點(G)的最少步數。
思路:從起點開始,定義一個數組d記錄可以走的路徑的最少步數,初始值設為0,向四個方向依次搜尋可以走的路徑,並將陣列d更新到從起點到當前位置的步數,當佇列不為空的時候,一直迴圈,直到佇列為空,返回陣列d記錄的最少步數。
AC程式碼如下:
(注意bfs的返回狀態)
#include <iostream> #include <queue> using namespace std; typedef pair<int,int> P; const int INF= 10000000; char maze[100][100];//定義陣列最大長度 int N,M;//迷宮行列數 int sx,sy,gx,gy;//迷宮起點終點座標 int d[100][100];//記錄走到該座標需要的最短步數 int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//記錄移動的四個方位, //求從sx,sy到gx,gy的最短距離,如果無法到達,則是INF int bfs()//走迷宮 { queue<P> que;//定義一個佇列 for(int i=0;i<N;i++) for(int j=0;j<M;j++) d[i][j]=INF; que.push(P(sx,sy));//將起點放進佇列中 d[sx][sy]=0;//到起點步數為0 while(que.size())//不斷迴圈直到佇列為空 { P p=que.front();//定義當前佇列頂端座標 為P que.pop();//將P彈出 if(p.first==gx&&p.second==gy) break;//判斷該座標是否是終點,是的話結束 for(int i=0;i<4;i++)//使座標不斷向四個方向移動 { int nx=p.first+dx[i]; int ny=p.second+dy[i]; if(0<=nx&&nx<N&&0<=ny&&ny<=M&&maze[nx][ny]!='#'&&d[nx][ny]==INF)//當前座標某方位是否可移動以及是否以及訪問過(d[nx][ny]!=INF即為已經訪問過) { //如果座標當前某方向可移動 que.push(P(nx,ny)); //則將該位置該點座標放入佇列中 d[nx][ny]=d[p.first][p.second]+1; //記錄該位置的最短步數=上一位置到達步數+1 } } } return d[gx][gy]; } int main() { cin>>N>>M; for(int i=0;i<N;i++) for(int j=0;j<M;j++) cin>>maze[i][j]; for(int i=0;i<N;i++) for(int j=0;j<M;j++) { if(maze[i][j]=='S') { sx=i;sy=j; } if(maze[i][j]=='G') { gx=i;gy=j; } } int res=bfs(); cout<<res<<endl; return 0; }