一個讓我想死的題目,怎麼想都沒有想到這個題要用廣度優先搜索。而且,題目說了,能左轉走,能右轉走,不能倒着走。妹的,最後一想,我轉2次方向,就面向背面了,相當於“往後轉”。而且,“走”,和“轉”要分開。
1、輸入地圖,初始化相關存儲變量。
2、廣度優先搜索,注意狀態記錄,“走”,和“轉”要分開。
3、輸出結果,判斷搜索情況,搜索是否成功。
#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #define size 27 //最大範圍25 using namespace std; int n,m; int sx,sy,ex,ey; //起始點,終點座標 int map[size][size]; //存儲地圖信息,“-1”不能走,“1”能走 bool flag[size][size][5][4]; //存儲搜索狀態信息,狀態標記【x座標】【y座標】【顏色】【方向】 int dir[4][2]={1,0,0,1,-1,0,0,-1}; //四個搜索方向 struct node //節點信息結構體 { int x; //座標 int y; int step; int time; //耗時 int dict; //方向 int color; //顏色 bool operator <(const node &a)const{ //優先隊列,時間小的優先 return time>a.time; } }e,s; void initial() //信息初始化 { char x[size]; //臨時存儲地圖信息 int i,j; memset(map,-1,sizeof(map)); //地圖信息初始化,不能走 memset(flag,false,sizeof(flag)); //狀態標記數組初始化,所有情況都未遍歷 for(i=0;i<n;i++) //輸入處理地圖信息 { cin>>x; for(j=0;j<m;j++) { if(x[j]=='.')map[i][j]=0; //此處可走 else if(x[j]=='S')sx=i,sy=j,map[i][j]=0; //起始點 else if(x[j]=='T')ex=i,ey=j,map[i][j]=0; //終點 } } } bool inmap(int x,int y) //(x,y)點是否在地圖(有效)範圍內 { return x>=0&&x<n&&y>=0&&y<m; } int bfs() //廣度優先搜索尋路 { int i,j; priority_queue<node> q; s.x=sx; //其實節點初始化 s.y=sy; s.time=0; s.step=0; s.dict=2; //起始方向朝北,根據個人方向數組資料,數據不盡相同 s.color=0; //管它開始什麼顏色,方正總共只有5種顏色,最後停下來的時候,還是這個顏色(編號數字相同)就好了 flag[sx][sy][0][2]=true; q.push(s); while(!q.empty()) { s=q.top(); q.pop(); for(i=0;i<4;i++) //四個方向搜索 { e.x=s.x+dir[i][0]; e.y=s.y+dir[i][1]; e.time=s.time+1; e.step=s.step+1; e.dict=i; e.color=(s.color+1)%5; if(!inmap(e.x,e.y)||map[e.x][e.y]==-1) continue; //該點不在地圖內,該點不可處理 if(e.dict!=s.dict) //方向不同,先轉向,不要急着走格子 { if(e.dict==s.dict+2||e.dict==s.dict-2)e.time++; //反向,要轉2次 e.color=s.color; e.x=s.x; //位置不變,顏色不變 e.y=s.y; } if(flag[e.x][e.y][e.color][e.dict]) continue; //這個狀態以前走過,不再處理 flag[e.x][e.y][e.color][e.dict]=true; //要處理,標記 if(e.x==ex&&e.y==ey&&e.color==0)return e.time; //走到終點,顏色符合要求,搜索成功 map[e.x][e.y]=e.step; q.push(e); } } return -1; //搜索失敗 } int main() { int j=1; while(cin>>n>>m&&n+m) { initial(); //信息初始化 int ans= bfs(); //廣度優先搜索得答案 if(j!=1)cout<<endl; //案例中間有空行 cout<<"Case #"<<j++<<endl; if(ans==-1)cout<<"destination not reachable"<<endl; //搜索失敗 else cout<<"minimum time = "<<ans<<" sec"<<endl; //搜索成功 } return 0; }