1. 程式人生 > >HDOJ 1728 逃離迷宮(BFS,拐彎次數最少)

HDOJ 1728 逃離迷宮(BFS,拐彎次數最少)

開始拿到這道題,想到先前寫過的BFS,由出口到終點,最短路徑。後來一看題目不是這個意思,題目要求拐彎數最少到達終點而不是求最短路徑。
看了解題報告,有了一點點思路,就是先選定一條方向,然後把該方向上所有能拐的彎都拐了。也就是說,運動的方向不僅僅是周圍的四個點,因為沒求最短時間,為了避免BFS提前結束,就把四個方向搜尋到底。
注意,這裡記錄拐彎數的K的初始值不是0而是-1,因為第一個選定的方向不算在內。
PS:這道題目好坑啊,題目給的x是列,y是行,為了方便自己理解,我在輸入的時候特地先輸入y後輸入x,然後就可以當做正常理解的x,y。

然而這題卡我最多的是我沒有memset,vis的陣列沒有初始化。。。。所以養成良好的程式設計習慣很重要,一定要初始化陣列。

AC:

#include<iostream>
#include<cstdio>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define maxn 110
struct node{
    int x,y,d; //d存放之前已經拐彎次數
};
int x1,y1,x2,y2,k,n,m,t;
char mp[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2]={1,0,-1,0,0,1
,0,-1}; void bfs(node vs,node vd){ int flag=0; node sta,end; queue<node > que; sta.x =vs.x; sta.y =vs.y ;sta.d=-1; //第一次之前-1 vis[vs.x][vs.y]=true; que.push (sta); while(!que.empty ()){ sta=que.front (); que.pop(); if(sta.x==vd.x && sta.y==vd.y && sta.d<=k){ flag=1
;break; } end.d=sta.d+1; //前面搜完了一個方向肯定要拐彎 { int i; for(i=0;i<4;i++){ int nx=sta.x +dir[i][0]; int ny=sta.y+dir[i][1]; while(nx>=0 &&nx<n &&ny>=0 &&ny<m &&mp[nx][ny]!='*'){ if(!vis[nx][ny]){ end.x=nx; end.y=ny; que.push(end); vis[nx][ny]=true; } nx+=dir[i][0]; //單方向優先擴充套件 ny+=dir[i][1]; } } } } printf("%s\n",flag?"yes":"no"); } int main(){ int i,j; cin>>t; while(t--){ node vs,vd; memset(vis,false,sizeof(vis));//初始化!! cin>>n>>m; for(i=0;i<n;i++){ for(j=0;j<m;j++){ cin>>mp[i][j]; } } cin>>k>>y1>>x1>>y2>>x2; vs.x=x1-1;vs.y=y1-1; vd.x=x2-1;vd.y=y2-1; bfs(vs,vd); } return 0; }