1. 程式人生 > >迷宮問題(路徑輸出)

迷宮問題(路徑輸出)

Description

定義一個二維陣列: 

int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};


它表示一個迷宮,其中的1表示牆壁,0表示可以走的路,只能橫著走或豎著走,不能斜著走,要求程式設計序找出從左上角到右下角的最短路線。

Input

一個5 × 5的二維陣列,表示一個迷宮。資料保證有唯一解。

Output

左上角到右下角的最短路徑,格式如樣例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

這道題是傳統的迷宮搜尋題,我感覺難辦在路徑的輸出上,一開始試圖開一個結構體記錄。。。但後來發現。。。

迷宮搜尋的兩種方法:bfs和dfs,個人覺得bfs簡單一點。。畢竟不用遞迴。。。因此就先試了試bfs的,dfs應該會更新。。應該會研究一下。。。

bfs篇:

好了,現在開一個結構體記錄路徑,用到了一個deque的容器,【然後每次記錄路徑,然後把這個路徑存到一個佇列中】這裡非常重要!!是核心!!,用bfs解決。。。

不清楚deque的可以查一下或者看一下這個連結大笑

ok也可以看程式碼,程式碼我上面註釋我感覺比較詳細了。。。。

ac:程式碼有點長。。但大部分都是標頭檔案。。遇到個新的就加上去。。已經這麼多了啊。。

#include<stdio.h>
#include<string.h>
#include<math.h>

//#include<map>                                        //這裡map會衝突。。。
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

#define ll long long
#define da    0x3f3f3f3f
#define xiao -0x3f3f3f3f
#define clean(a,b) memset(a,b,sizeof(a))// 雷打不動的標頭檔案

//嘗試bfs路徑。。
struct dop{							//座標(點)	 
	int x,y;
};
struct rode{						//路徑 
	deque<dop> r;					//路徑佇列 (點的集合) 
};

int fx[4]={0,0,-1,1},fy[4]={-1,1,0,0};//方向 
int map[10][10];					//地圖 
int biaoji[10][10];					//是否走過 
int l[10][10];						//路徑長度 

int main()
{
	clean(biaoji,0);				//初始化 
	clean(map,0);
	int i,j,k=0;
	for(i=0;i<5;++i)
	{
		for(j=0;j<5;++j)
			cin>>map[i][j];			//輸入地圖 
	}
	dop a;							//初始點(起點) 
	a.x=0;
	a.y=0;
	biaoji[0][0]=1;					//起點標記 
	rode r;
	r.r.push_back(a); 				//起點加入路徑 
	queue<rode> q;					//一個路徑的佇列
	q.push(r);						//路徑入列 
	while(q.size())					//存在路徑 
	{
		rode nr=q.front();			//提取第一個路徑 
		dop nd=nr.r.back();			//現在的點(位置)
		//輸出最終的路徑 
		if(nd.x==4&&nd.y==4)		//如果到了目標點 
		{
			//printf("%d\n",l[4][4]);//這個是我看路徑長度的。。題上沒有要求。。 
			while(nr.r.size())		//如果該佇列的點(路徑)仍存在 
			{
				dop cand;			//定義該點 
				cand=nr.r.front();	//該點是隊首元素(點) 
				printf("(%d, %d)\n",cand.x,cand.y);//輸出 注意中間有個空格!!!wa了幾次。。。 
				nr.r.pop_front();	//將隊首元素釋放 
			}
			return 0;
		}
		
		q.pop();					// 將該路徑的釋放 
		for(i=0;i<4;++i)			//四個方向移動 
		{
			rode canr=nr;			//避免對一開始的路徑影響(加入條引數路徑) 
			int nx=nd.x+fx[i],ny=nd.y+fy[i];//向四周移動 
			if(nx>=0&&nx<5&&ny>=0&&ny<5)	//在地圖上
			{
				if(map[nx][ny]!=1&&biaoji[nx][ny]==0)//不是牆&&沒走過 
				{
					dop cand;		//定義一個點 
					cand.x=nx;		//x座標 
					cand.y=ny;		//y座標 
					canr.r.push_back(cand);//將這個點放入現在這個路徑的,路徑(點)中 
					q.push(canr);		//將這個路徑加入佇列 
					biaoji[nx][ny]=1;//標記該點走過了 
					l[nx][ny]=l[nd.x][nd.y]+1;//記錄步數 
				}
			}
		}
	}
	return 0;
}

dfs篇:

額。。。dfs。。未完待續。。。

唉唉唉點個贊再走啊抓狂。。抓狂