题意:
迷宫里起火了,有若干个障碍物,有多个起火点,起火点每经过一个时间间隔就向它的上下左右相邻的格子扩散。
有个倒霉的人好像叫做“Joe”,他要逃出来,他每次可以向上下左右任意移动一格,但是即要避开火也要避开障碍物,问你他如果逃得出来的话至少要多少步。
没有着火点的话就直接,bfs了,但是有的话就稍微与处理一下,我们可以通过对着火点bfs,从而知道每个格子在什么时间着火。
这样的话,只要先bfs着火点,把每个格子在什么时间着火保存到数组里;然后bfs那个人,在判断他可不可以那个格子的check函数增加一步,检查他走过去的时间是不是小于起火的时间。
源代码:
1 #include <stdio.h> 2 #include <string.h> 3 const int maxn=1010; 4 const int sizeq=1000005; 5 bool vis[maxn][maxn]; 6 int fi[maxn][maxn],dis[maxn][maxn]; 7 char map[maxn][maxn]; 8 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 9 int T,R,C,ans; 10 bool flag; 11 12 struct Node{ 13 int x,y; 14 }; 15 Node q[sizeq]; 16 int font,rear; 17 void Enqueue(Node x) 18 { 19 q[rear++]=x; 20 if(rear==sizeq) rear=0; 21 } 22 Node Dequeue() 23 { 24 Node z=q[font++]; 25 if(font==sizeq) font=0; 26 return z; 27 } 28 bool check(Node nd) 29 { 30 return nd.x<0||nd.y<0||nd.x>=R||nd.y>=C||map[nd.x][nd.y]=='#'||vis[nd.x][nd.y]; 31 } 32 void fire() 33 { 34 Node f,nx; 35 memset(fi,0,sizeof(fi)); 36 memset(vis,0,sizeof(vis)); 37 font=rear=0; 38 for(int i=0;i<R;i++){ 39 for(int j=0;j<C;j++){ 40 if(map[i][j]=='F'){ 41 f.x=i; 42 f.y=j; 43 fi[i][j]=1; 44 vis[i][j]=1; 45 Enqueue(f); 46 } 47 } 48 } 49 while(font!=rear){ 50 f=Dequeue(); 51 for(int i=0;i<4;i++){ 52 nx.x=f.x+dir[i][0]; 53 nx.y=f.y+dir[i][1]; 54 if(check(nx))continue; 55 fi[nx.x][nx.y]=fi[f.x][f.y]+1; 56 vis[nx.x][nx.y]=1; 57 Enqueue(nx); 58 } 59 } 60 } 61 62 bool safe(Node x,int d) 63 { 64 return !check(x) && (fi[x.x][x.y]>d||fi[x.x][x.y]==0); 65 } 66 67 int bfs() 68 { 69 Node u,v; 70 font=rear=0; 71 memset(dis,0,sizeof(dis)); 72 memset(vis,0,sizeof(vis)); 73 for(int i=0;i<R;i++){ 74 for(int j=0;j<C;j++){ 75 if(map[i][j]=='J'){ 76 u.x=i; 77 u.y=j; 78 Enqueue(u); 79 vis[i][j]=1; 80 dis[i][j]=1; 81 } 82 } 83 } 84 while(font!=rear){ 85 u=Dequeue(); 86 if(u.x==0||u.x==R-1||u.y==0||u.y==C-1){ 87 return dis[u.x][u.y]; 88 } 89 for(int i=0;i<4;i++){ 90 v.x=u.x+dir[i][0]; 91 v.y=u.y+dir[i][1]; 92 if(!safe(v,dis[u.x][u.y]+1))continue; 93 Enqueue(v); 94 vis[v.x][v.y]=1; 95 dis[v.x][v.y]=dis[u.x][u.y]+1; 96 } 97 } 98 return 0; 99 } 100 101 int main() 102 { 103 scanf("%d",&T); 104 while(T--){ 105 scanf("%d %d",&R,&C); 106 for(int i=0;i<R;i++)scanf("%s",map[i]); 107 fire(); 108 ans=bfs(); 109 if(ans){ 110 printf("%d\n",ans); 111 }else{ 112 puts("IMPOSSIBLE"); 113 } 114 } 115 116 }