hdu1180-詭異的樓梯(bfs+優先佇列)
阿新 • • 發佈:2019-02-13
詭異的樓梯
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 11689 Accepted Submission(s): 2895
Problem Description Hogwarts正式開學以後,Harry發現在Hogwarts裡,某些樓梯並不是靜止不動的,相反,他們每隔一分鐘就變動一次方向.
比如下面的例子裡,一開始樓梯在豎直方向,一分鐘以後它移動到了水平方向,再過一分鐘它又回到了豎直方向.Harry發現對他來說很難找到能使得他最快到達目的地的路線,這時Ron(Harry最好的朋友)告訴Harry正好有一個魔法道具可以幫助他尋找這樣的路線,而那個魔法道具上的咒語,正是由你纂寫的.
Input 測試資料有多組,每組的表述如下:
第一行有兩個數,M和N,接下來是一個M行N列的地圖,'*'表示障礙物,'.'表示走廊,'|'或者'-'表示一個樓梯,並且標明瞭它在一開始時所處的位置:'|'表示的樓梯在最開始是豎直方向,'-'表示的樓梯在一開始是水平方向.地圖中還有一個'S'是起點,'T'是目標,0<=M,N<=20,地圖中不會出現兩個相連的梯子.Harry每秒只能停留在'.'或'S'和'T'所標記的格子內.
Output 只有一行,包含一個數T,表示到達目標的最短時間.
注意:Harry只能每次走到相鄰的格子而不能斜走,每移動一次恰好為一分鐘,並且Harry登上樓梯並經過樓梯到達對面的整個過程只需要一分鐘,Harry從來不在樓梯上停留.並且每次樓梯都恰好在Harry移動完畢以後才改變方向.
Sample Input 5 5 **..T **.*. ..|.. .*.*. S....
Sample Output 7 Hint
分析:如何對樓梯的情況進行處理是關鍵,當我們碰到樓梯的時候,我們可以選擇等待,或直接走過去,且樓梯會動態變化。要對時間進行奇偶分類,來判斷樓梯的狀態,且對是否等待進行操作。利用優先佇列,使時間短的先走。還有一個非常關鍵的點,就是vis陣列的處理。詳見程式碼。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <queue> #define INF 0x3f3f3f3f #define Pn printf("\n") #define CSH(a, b) memset(a, (b), sizeof(a)) #define ll long long #define PRnode(q) priority_queue<node> q using namespace std; char s[25][25]; int dir[4][2]={-1,0, 1,0, 0,-1, 0,1}; int vis[25][25]; struct node { int x; int y; int ti; bool operator < (const node &a) const { return ti>a.ti;//小值優先 } }; int main() { int m,n; while(~scanf("%d%d",&n,&m)) { node fr; int flag=0,ans=0; CSH(vis,-1); for(int i=0;i<n;i++) { getchar(); for(int j=0;j<m;j++) { scanf("%c",&s[i][j]); if(s[i][j]=='S') { fr.x=i; fr.y=j; fr.ti=0; vis[i][j]=0; } } } PRnode(q); while(!q.empty()) { q.pop(); } q.push(fr); while(!q.empty()) { node ne; ne=q.top(); q.pop(); for(int i=0;i<4;i++) { node no; no.x=ne.x+dir[i][0]; no.y=ne.y+dir[i][1]; no.ti=ne.ti; if(s[no.x][no.y]!='*'&&no.x>=0&&no.x<n&&no.y>=0&&no.y<m&&vis[no.x][no.y]<no.ti) { if(s[no.x][no.y]=='|') { if(no.ti%2) { if(i==3&&s[no.x][no.y+1]!='*'&&no.y+1<m) { vis[no.x][no.y]=no.ti; no.y+=1; no.ti++; } else if(i==2&&s[no.x][no.y-1]!='*'&&no.y-1>=0) { vis[no.x][no.y]=no.ti; no.y-=1; no.ti++; } else { no.x-=dir[i][0]; no.y-=dir[i][1]; no.ti++; } } else { if(i==1&&s[no.x+1][no.y]!='*'&&no.x+1<n) { vis[no.x][no.y]=no.ti; no.x+=1; no.ti++; } else if(i==0&&s[no.x-1][no.y]!='*'&&no.x-1>=0) { vis[no.x][no.y]=no.ti; no.x-=1; no.ti++; } else { no.x-=dir[i][0]; no.y-=dir[i][1]; no.ti++; } } if(s[no.x][no.y]=='T') { no.ti++; flag=2; ans=no.ti; break; } } else if(s[no.x][no.y]=='-') { if(no.ti%2) { if(i==1&&s[no.x+1][no.y]!='*'&&no.x+1<n) { vis[no.x][no.y]=no.ti; no.x+=1; no.ti++; } else if(i==0&&s[no.x-1][no.y]!='*'&&no.x-1>=0) { vis[no.x][no.y]=no.ti; no.x-=1; no.ti++; } else { no.x-=dir[i][0]; no.y-=dir[i][1]; no.ti++; } } else { if(i==3&&s[no.x][no.y+1]!='*'&&no.y+1<m) { vis[no.x][no.y]=no.ti; no.y+=1; no.ti++; } else if(i==2&&s[no.x][no.y-1]!='*'&&no.y-1>=0) { vis[no.x][no.y]=no.ti; no.y-=1; no.ti++; } else { no.x-=dir[i][0]; no.y-=dir[i][1]; no.ti++; } } if(s[no.x][no.y]=='T') { no.ti++; flag=2; ans=no.ti; break; } } else if(s[no.x][no.y]=='.') { no.ti++; } else if(s[no.x][no.y]=='T') { no.ti++; flag=1; ans=no.ti; break; } if(s[no.x][no.y]=='.') { vis[no.x][no.y]=no.ti; } q.push(no); } } if(flag) { break; } } flag==1?printf("%d\n",ans):printf("%d\n",ans-1); } }