1. 程式人生 > >杭電acm 1180 詭異的樓梯 BFS

杭電acm 1180 詭異的樓梯 BFS

script 朋友 mission emp temp ont pty content using

詭異的樓梯

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 19334 Accepted Submission(s): 5048

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 Hint 地圖如下: 技術分享圖片 這道題和逃出迷宮一樣都是使用BFS算法,但是不同的是他要求的是時間,所以有部分修改了,註意。
  1 #include<iostream>
  2 #include<queue>
  3 #include<string.h>
  4 using namespace std;
  5 
  6 struct Node{
  7     int x,y,time;
8 }; 9 int M,N;//地圖大小 10 char map[25][25]; 11 int vis[25][25]; 12 int xy[4][2]={0,1,0,-1,1,0,-1,0};//方向 13 int start_x,start_y,end_x,end_y;//初始點和結束點 14 queue<Node>que; 15 Node node; 16 17 bool check(int x,int y){//檢查當前點能不能走,是不是走過的 18 if(x>=0&&x<M&&y>=0&&y<N&&map[x][y]!=
*&&!vis[x][y]) 19 return true; 20 else return false; 21 } 22 bool check(int x,int y,int z){//檢測當遇到樓梯時,樓梯對面能不能走 23 if(z==N){ 24 if(y>=0&&y<z&&map[x][y]!=*&&!vis[x][y]) 25 return true; 26 else return false; 27 } 28 else { 29 if(x>=0&&x<M&&map[x][y]!=*&&!vis[x][y]) 30 return true; 31 else return false; 32 } 33 } 34 void push_p(int x,int y,int time){//用來保存每個沒有走過的點 35 Node temp; 36 temp.x=x;temp.y=y;temp.time=time+1; 37 que.push(temp); 38 return; 39 } 40 41 int BFS(){ 42 int fx,fy;//是下一步將要走到的坐標 43 node.x=start_x; 44 node.y=start_y; 45 node.time=0; 46 que.push(node); 47 while(!que.empty()){ 48 node=que.front(); 49 que.pop(); 50 if(node.x==end_x&&node.y==end_y){//到達終點 51 return node.time; 52 } 53 for(int i=0;i<4;++i){//4個方向走 54 fx=node.x+xy[i][0]; 55 fy=node.y+xy[i][1]; 56 if(check(fx,fy)){//檢查下一個點能不能走 57 if(map[fx][fy]==.||map[fx][fy]==T){//如果不是樓梯,就保存下下一個能走的點 58 push_p(fx,fy,node.time); 59 vis[fx][fy]=1; 60 } 61 else if(map[fx][fy]==-){//如果地圖上是橫著的樓梯 62 if(node.time%2==0){//那麽在偶數時間 它是橫著的樓梯 63 if(fx==node.x){//看看他是不是橫著走過來的 64 if(node.y+1==fy){ 65 fy+=1; 66 } 67 else{ 68 fy-=1; 69 } 70 if(check(fx,fy,N)){//檢查樓梯對面 能不能走 71 push_p(fx,fy,node.time); 72 vis[fx][fy]=1; 73 } 74 } 75 else{//如果不是橫著走過來的就停下等候樓梯 76 push_p(node.x,node.y,node.time); 77 } 78 } 79 else if(node.time%2!=0){//在奇數時間,它是縱著的樓梯 80 if(fy==node.y){//判斷他是不是縱著走過來的 81 if(node.x+1==fx){ 82 fx++; 83 } 84 else{ 85 fx--; 86 } 87 if(check(fx,fy,M)){//判斷他能不能到達樓梯對面 88 push_p(fx,fy,node.time); 89 vis[fx][fy]=1; 90 } 91 } 92 else{//如果不是縱著走過來的就停下等候樓梯 93 push_p(node.x,node.y,node.time); 94 } 95 } 96 } 97 else if(map[fx][fy]==|){//如果地圖上的樓梯是縱著的,意思同上 98 if(node.time%2==0){ 99 if(fy==node.y){ 100 if(node.x+1==fx) fx++; 101 else fx--; 102 if(check(fx,fy,M)){ 103 push_p(fx,fy,node.time); 104 vis[fx][fy]=1; 105 } 106 } 107 else{ 108 push_p(node.x,node.y,node.time); 109 } 110 } 111 else{ 112 if(fx==node.x){ 113 if(node.y+1==fy)fy++; 114 else fy--; 115 if(check(fx,fy,N)){ 116 push_p(fx,fy,node.time); 117 vis[fx][fy]=1; 118 } 119 } 120 else{ 121 push_p(node.x,node.y,node.time); 122 } 123 } 124 } 125 } 126 } 127 } 128 } 129 int main(){ 130 while(cin>>M>>N){ 131 memset(vis,0,sizeof(vis));//初始化用來保存地圖上哪個點已經被走過的參數 132 for(int i=0;i<M;i++){//保存下地圖 133 for(int j=0;j<N;j++){ 134 cin>>map[i][j]; 135 if(map[i][j]==S||map[i][j]==s){//標記初始點 136 start_x=i; 137 start_y=j; 138 } 139 if(map[i][j]==T||map[i][j]==t){//標記結束點 140 end_x=i; 141 end_y=j; 142 } 143 } 144 } 145 vis[start_x][start_y]=1;//初始點被走過 146 while(!que.empty()){//清空隊列 147 que.pop(); 148 } 149 int ans=BFS();//獲得所走的時間 150 cout<<ans<<endl; 151 } 152 }

杭電acm 1180 詭異的樓梯 BFS