1. 程式人生 > >Hero In Maze(BFS廣搜)

Hero In Maze(BFS廣搜)

天數 ring ++ har 隊列 count 解題思路 包括 ios

Description

500年前,Jesse是我國最卓越的劍客。他英俊瀟灑,而且機智過人^_^。
突然有一天,Jesse心愛的公主被魔王困在了一個巨大的迷宮中。Jesse聽說這個消息已經是兩天以後了,他知道公主在迷宮中還能堅持T天,他急忙趕到迷宮,開始到處尋找公主的下落。 時間一點一點的過去,Jesse還是無法找到公主。最後當他找到公主的時候,美麗的公主已經死了。從此Jesse郁郁寡歡,茶飯不思,一年後追隨公主而去了。T_T 500年後的今天,Jesse托夢給你,希望你幫他判斷一下當年他是否有機會在給定的時間內找到公主。
他會為你提供迷宮的地圖以及所剩的時間T。請你判斷他是否能救出心愛的公主。

Input

題目包括多組測試數據。 每組測試數據以三個整數N,M,T(0<n, m≤20, t>0)開頭,分別代表迷宮的長和高,以及公主能堅持的天數。 緊接著有M行,N列字符,由".","*","P","S"組成。其中 "." 代表能夠行走的空地。 "*" 代表墻壁,Jesse不能從此通過。 "P" 是公主所在的位置。 "S" 是Jesse的起始位置。 每個時間段裏Jesse只能選擇“上、下、左、右”任意一方向走一步。 輸入以0 0 0結束。

Output

如果能在規定時間內救出公主輸出“YES”,否則輸出“NO”。

Sample Input

4 4 10
....
....
....
S**P
0 0 0

Sample Output

YES


解題思路:
廣度優先搜索使用隊列(queue)來實現,整個過程也可以看做一個倒立的樹形: 1、把根節點放到隊列的末尾。 2、每次從隊列的頭部取出一個元素,查看這個元素所有的下一級元素,把它們放到隊列的末尾。並把這個元素記為它下一級元素的前驅。 3、找到所要找的元素時結束程序。 4、如果遍歷整個樹還沒有找到,結束程序。
#include <iostream>
#include <stdio.h>
#include
<string.h> #include<queue> using namespace std; char map[25][25]; int vis[25][25]; int dir[4][2]= { {1,0},{-1,0},{0,1},{0,-1} }; int n,ans,m,num,c,d; struct state { int x; int y; int count; }; int bfs(int x,int y) { queue<state>p; struct state now,t,beg; beg.x=x; beg.y=y; beg.count=0; vis[x][y]=1; p.push(beg); while(!p.empty()) { int i,a,b; t=p.front(); if(t.x==c&&t.y==d) { return t.count; }///找到了公主 for(i=0; i<4; i++) { a=t.x+dir[i][0]; b=t.y+dir[i][1]; if(a>=1&&a<=m&&b>=1&&b<=n&&vis[a][b]==0 ) { now.count=t.count+1; vis[a][b]=1; now.x=a; now.y=b; p.push(now); } } p.pop(); } return 10000000;///如果隊列已經清空了(可以認為該劍客走上了絕路,到達不了囚禁公主的地方,返回一個超大的數) } int main() { while(scanf("%d%d%d",&n,&m,&num)!=EOF) { if(n==0&&m==0&&num==0) break; int i,j,a,b; memset(map,0,sizeof(map)); memset(vis,0,sizeof(vis)); for(i=1; i<=m; i++) { for(j=1; j<=n; j++) { scanf(" %c",&map[i][j]); if(map[i][j]==S)///起始位置 { a=i; b=j; } else if(map[i][j]==*)///*代表墻,不能過 vis[i][j]=1; else if(map[i][j]==P)///公主的位置 { c=i; d=j; } } } ans=bfs(a,b); if(ans>num) printf("NO\n"); else printf("YES\n"); } return 0; }

Hero In Maze(BFS廣搜)