BFS模板題——迷宮

前言

BFS模板題

正文

【問題描述】

下圖給出了一個迷宮的平面圖,其中標記爲 1 的爲障礙,標記爲 0 的爲可以通行的地方。
010000
000100
001001
110000

迷宮的入口爲左上角,出口爲右下角,在迷宮中,只能從一個位置走到這 個它的上、下、左、右四個方向之一。
對於上面的迷宮,從入口開始,可以按DRRURRDDDR 的順序通過迷宮, 一共 10 步。其中 D、U、L、R 分別表示向下、向上、向左、向右走。
對於下面這個更復雜的迷宮(30 行 50 列),請找出一種通過迷宮的方式,其使用的步數最少,在步數最少的前提下,請找出字典序最小的一個作爲答案。請注意在字典序中D<L<R<U。(如果你把以下文字複製到文本文件中,請務 必檢查複製的內容是否與文檔中的一致。在試題目錄下有一個文件 maze.txt, 內容與下面的文本相同)

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

【答案提交】
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一 個字符串,包含四種字母 D、U、L、R,在提交答案時只填寫這個字符串,填寫多餘的內容將無法得分。


知識點

廣度優先搜索(BFS)算法類似於樹中的層次搜索:
從任意點p出發,先遍歷與p相鄰的點,然後再遍歷於相鄰的點相鄰的點。注意有向圖必須是順方向的鄰接點。爲什麼說廣度優先搜索可以用來求無權最短路徑呢?因爲,廣度優先搜索每次都會先發現距離p爲k的所有頂點,然後纔會發現距離p爲k+1的所有頂點(p爲起始點)。

深度優先搜索相當於一個人在走迷宮,廣搜相當於是無窮人沿着不同方向走(因爲每條路都同時有人走)。
DFS相當於是一個下壓棧。是先進後出的原則(如果找不到,往回走,直到回到有路的地方)(DFS隱式使用了棧)
BFS使用隊列,按照與起點的距離來搜索。
BFS使用一個隊列來保存已經被標記但是它的鄰接表還沒有被訪問的頂點。先把起點加入隊列,然後重複以下操作直到隊列爲空。
1、取隊列中下一個頂點V並標記它
2、把和V相鄰的所有沒有標記的頂點加入隊列。
BFS的標記edgeto代表了它的上一個節點,它的上一個節點一定只有一種情況,代表了最短解(不一定是唯一的)。

深度優先搜索優先尋找離起點最遠的頂點,廣度優先搜索最先找最近的頂點

思路

走迷宮,而且是最短的路徑,可以用BFS按照開始狀態由近及遠的順序進行搜索,由於字典序中D<L<R<U,因此在搜索路徑的時候就可以按照字典序的順序來安排搜索方向的先後順序。

參考題解

#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
/*
輸入n,m表示n行m列的地圖 
*/
int vis[100][100];//標記數組 
int dir[4][2]={{1,0},{0,-1},{0,1},{-1,0}};//(移動的方向,對應D、L、R、U,向下則x+1,y不變,所以對應{1,0}) 
char ch[4]={'D','L','R','U'};//記錄方向 
int n,m;
struct point{
	int x,y;
	string path;
};
void bfs(){
	queue<point> q;
	struct point p={
		0,0,""
	};
	q.push(p);//起始點入隊列 
	vis[0][0]=1;//起始點被訪問 
	while(!q.empty()){//隊列非空 
		struct point temp=q.front();
		q.pop();
		int curX=temp.x,curY=temp.y;
		if(curX==n-1&&curY==m-1){//到達終點,輸出路徑 
			cout<<temp.path<<endl;
		}else{
			for(int i=0;i<4;i++){//循環遍歷D、L、R、U四個方向
				int nx=temp.x+dir[i][0];
				int ny=temp.y+dir[i][1]; 
				if(nx>=0&&nx<=n-1&&ny>=0&&ny<=m-1&&vis[nx][ny]==0){//未超出地圖範圍且未被訪問 
					q.push({nx,ny,temp.path+ch[i]});//加入隊列
					vis[nx][ny]=1;//設置該點已被訪問 
				}
			}
		} 
	}
} 
int main(){
	char next_char;
	cin>>n>>m;
	char map[n][m];
	cin.get(next_char);//讀取換行符 
	//讀取地圖 
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin.get(next_char);
			map[i][j]=next_char;
			if(map[i][j]=='0')vis[i][j]=0;
			else vis[i][j]=1;
		}
		cin.get(next_char); 
	}
	bfs();
	return 0;
} 


輸入:30 50
輸出: DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

參考鏈接

https://blog.csdn.net/qq_43680117/article/details/84033882

後記

注意複製迷宮數據的時候,會同時複製csdn的版權信息噢

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