HDU 1180 詭異的樓梯(BFS+優先佇列)
阿新 • • 發佈:2019-01-30
詭異的樓梯Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 13186 Accepted Submission(s): 3318 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 |
本題與簡單B模板BFS題的區別就在於對樓梯的處理。這值得注意的一點就是要考慮等樓梯的情況。
因為這種情況的存在,因此採用優先佇列保證得到的時間是最小的。
具體對樓梯的處理體現在程式碼中。
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> #include<vector> #include<math.h> #include<queue> #include<stack> using namespace std; char map[1001][1001]; int vis[1001][1001]; int n,m,sx,sy,ex,ey; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1},}; bool legal(int x,int y) { if(x<1||y<1||x>n||y>m||vis[x][y]||map[x][y]=='*') return false; return true; } struct node { int x,y,t; }; struct cmp { bool operator()(node a,node b) { return a.t>b.t; } }; int bfs() { memset(vis,0,sizeof(vis)); node cur,next; cur.x=sx; cur.y=sy; cur.t=0; priority_queue<node,vector<node>,cmp> q; q.push(cur); while(!q.empty()) { cur=q.top(); q.pop(); if(cur.x==ex&&cur.y==ey) return cur.t; for(int i=0;i<4;i++) { next.x=cur.x+dir[i][0]; next.y=cur.y+dir[i][1]; next.t=cur.t+1; while(legal(next.x,next.y)) { if((i==0||i==1)&&map[next.x][next.y]=='|'&&cur.t%2==0) next.x=next.x+dir[i][0]; else if((i==0||i==1)&&map[next.x][next.y]=='-'&&cur.t%2==0) { next.x=next.x+dir[i][0]; next.t=next.t+1; } else if((i==0||i==1)&&map[next.x][next.y]=='-'&&cur.t%2==1) next.x=next.x+dir[i][0]; else if((i==0||i==1)&&map[next.x][next.y]=='|'&&cur.t%2==1) { next.x=next.x+dir[i][0]; next.t=next.t+1; } else if((i==2||i==3)&&map[next.x][next.y]=='|'&&cur.t%2==1) next.y=next.y+dir[i][1]; else if((i==2||i==3)&&map[next.x][next.y]=='|'&&cur.t%2==0) { next.y=next.y+dir[i][1]; next.t=next.t+1; } else if((i==2||i==3)&&map[next.x][next.y]=='-'&&cur.t%2==0) next.y=next.y+dir[i][1]; else if((i==2||i==3)&&map[next.x][next.y]=='-'&&cur.t%2==1) { next.y=next.y+dir[i][1]; next.t=next.t+1; } vis[next.x][next.y]=1; q.push(next); } } } } int main() { while(cin>>n>>m) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>map[i][j]; if(map[i][j]=='S') { sx=i; sy=j; map[i][j]='*'; } if(map[i][j]=='T') { ex=i; ey=j; } } cout<<bfs()<<endl; } return 0; }