hdu1072 逃离迷宫系列 bfs
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1072/
题意:逃离迷宫,路中可能有炸弹,总时间是6个单位,在有炸弹的位置,如果到达的时刻时间大于0,则恢复到6时间,炸弹的位置可以重复到达,求出最终至少需要多少步才能走出迷宫,到达终点。这样的最优化问题和地图相关的,bfs应该足以解决。我们考虑到一个位置可能被多次访问,所以状态参数应该设置一个时间,设置为访问时的剩余时间,因为如果一个位置第一次访问时剩余时间是t,则下一次访问时如果剩余时间还是t的话,走的步数一定比第一次访问时大,不可能是最优解,这也是一种剪枝。要注意每次时间状态更新时都要判断这个状态在已经搜索过的状态空间中是否存在。其次,判断状态不可到达的条件较多,在cur->nxt两种状态切换之间需要把所有的状态变化先列举出来。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define dbg(args) cout<<#args<<":"<<args<<endl; 17 #define inf 0x3f3f3f3f 18 #define maxn 105 19 int n,m,t,sx,sy,tx,ty; 20 int Map[maxn][maxn]; 21 int dir[][2]={0,1,0,-1,1,0,-1,0}; 22 struct node{ 23 int x,y,time,step; 24 }; 25 bool vis[maxn][maxn][maxn]; 26 //还需要考虑到走出迷宫的时间,所以一个位置可能在不同的时间被走到 27 //第一次在剩余t时间走到(i,j)位置时step一定最小 28 node cur,nxt; 29 int bfs() 30 { 31 queue<node>q; 32 node st; 33 st.x=sx,st.y=sy,st.time=6,st.step=0; 34 q.push(st); 35 vis[sx][sy][6]=true; 36 //一个位置如果有t时间剩余时就已经走到了,那下一次经过此地还是以t时间的话走的路程一定是更多了 37 while(!q.empty()) 38 { 39 cur=q.front(); 40 q.pop(); 41 if(cur.x==tx&&cur.y==ty&&cur.time>0) 42 { 43 return cur.step; 44 } 45 f(i,0,3) 46 { 47 nxt=cur; 48 nxt.x+=dir[i][0]; 49 nxt.y+=dir[i][1]; 50 nxt.time--; 51 nxt.step++; 52 //注意列举不能走的状态, 53 if(nxt.x<1||nxt.x>n||nxt.y<1||nxt.y>m||Map[nxt.x][nxt.y]==0||nxt.time<=0)continue; 54 if(vis[nxt.x][nxt.y][nxt.time])continue; 55 56 //由于时间是状态量,所以每次变化都必须检查访问过的状态空间中是否有该状态 57 if(Map[nxt.x][nxt.y]==4&&nxt.time>0) 58 { 59 nxt.time=6; 60 if(vis[nxt.x][nxt.y][nxt.time])continue; 61 } 62 vis[nxt.x][nxt.y][nxt.time]=1; 63 q.push(nxt); 64 } 65 } 66 return -1; 67 } 68 int main() 69 { 70 //freopen("input.txt","r",stdin); 71 //freopen("output.txt","w",stdout); 72 std::ios::sync_with_stdio(false); 73 scan(t); 74 while(t--) 75 { 76 mem(vis,false); 77 scan(n); 78 scan(m); 79 char c; 80 f(i,1,n) 81 f(j,1,m) 82 { 83 scanf(" %c",&c); 84 Map[i][j]=c-'0'; 85 if(Map[i][j]==3)tx=i,ty=j; 86 if(Map[i][j]==2)sx=i,sy=j; 87 } 88 pf("%d\n",bfs()); 89 } 90 }
每一个不曾起舞的日子,都是对生命的辜负。