1. 程式人生 > >《演算法筆記》——BFS-迷宮最短路問題

《演算法筆記》——BFS-迷宮最短路問題

題目大意:給定一個大小為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;
}