hdu 1072 Nightmare(BFS)
阿新 • • 發佈:2018-12-17
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1072
題目大意:逃出迷宮,有6秒的時間限制,但是可以通過到達4點來重置時間回到6秒,求最短時間。不能逃出輸出-1.
題目思路:算最短時間,用寬度優先搜尋,由於4點可以重複到達,因此不能直接標記所有走過的點。但是重複到達4點是沒有意義的,所以每個位置的4點最多經過1次,走過之後把它標記為牆就行了,不然會超記憶體。
AC程式碼:
#include <cstdio> #include <queue> #include <cstring> using namespace std; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; const int MAXN = 12; int mp[MAXN][MAXN]; int vis[MAXN][MAXN][MAXN]; int d[MAXN][MAXN]; struct node{ int x,y,t,dis; }; queue<node> q; int sx,sy,ex,ey; int n,m; int C(int x,int y,int t){ if(x>=0 && x<n && y>=0 &&y<m && mp[x][y]!=0 && !vis[x][y][t]) return 1; return 0; } int solve(){ memset(d,0,sizeof(d)); memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); q.push((node){sx,sy,6,0}); while(!q.empty()){ node now=q.front();q.pop(); vis[now.x][now.y][now.t]=1; for(int i=0;i<4;i++){ int dx=now.x+dir[i][0]; int dy=now.y+dir[i][1]; int tmp=now.t-1; if(C(dx,dy,tmp)&& tmp>0){ d[dx][dy]=d[now.x][now.y]+1; if(mp[dx][dy]==1 && tmp>0){ q.push((node){dx,dy,tmp,d[dx][dy]}); }else if(mp[dx][dy]==3 && tmp>0){ return d[dx][dy]; }else if(mp[dx][dy]==4 && tmp>0){ q.push((node){dx,dy,6,d[dx][dy]}); mp[dx][dy]=0; } } } } return -1; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ scanf("%d",&mp[i][j]); if(mp[i][j]==2){ sx=i; sy=j; } } } printf("%d\n",solve()); } return 0; }