要求:n*m的迷宫内,#表示不可以通过的墙,.表示可走的路,J表示逃离迷宫的人,F表示火,人每分钟可以移动一格,火每分钟向四个方向扩展一格。有一个J和多个F。问人是否可以逃出迷宫,逃出边界即算作逃出迷宫。若可以输出逃出的最短时间,不可以则输出IMPOSSIBLE。
方法:2次bfs
1.先对多处的火进行bfs,对每个火可以到达的格子标记几分钟后可以燃烧到。
2.对人进行bfs,向此时火燃烧不到的格子移动。
3.火不需used标记,因为时间起到了used的作用,人需要used标记。
4.下面的代码是对的,未解的2处疑惑注释已给出。(不规范写代码引起的问题,但着实好奇
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std ;
int n , m ;
int jx , jy , fx , fy ;
int ans ;
char map1[1005][1005] ;
int used[1005][1005] ;
int ftime1[1005][1005] ;
int row[4] = {0 , 0 , -1 , 1} ;
int col[4] = {-1 , 1 , 0 , 0} ;
struct node
{
int x , y ;
int time1 ;
} ;
queue<node>q ;
void fbfs()
{
int i , j ;
int x1 , y1 , x2 , y2 ;
node a , b ;
while(!q.empty())
q.pop() ;
a.x = fx ;
a.y = fy ;
ftime1[a.x][a.y] = 0 ;
q.push(a) ;
while(!q.empty())
{
a = q.front() ;
q.pop() ;
for(i = 0 ; i < 4 ; i ++)
{
x1 = a.x + row[i] ;
y1 = a.y + col[i] ;
if(x1 >= 0 && x1 < n && y1 >= 0 && y1 < m
&& (map1[x1][y1] == 'F' || map1[x1][y1] == '.' || map1[x1][y1] == 'J')
//疑惑1:为什么上面的那一句换成了 map1[x1][y1] != '#'之后就不可以了
&& ftime1[a.x][a.y] + 1 < ftime1[x1][y1])
{
ftime1[x1][y1] = ftime1[a.x][a.y] + 1 ;
b.x = x1 ;
b.y = y1 ;
q.push(b) ;
}
}
}
}
void bfs()
{
int i , j ;
int x1 , y1 , x2 , y2 ;
node a , b ;
while(!q.empty())
q.pop() ;
memset(used , 0 , sizeof(used)) ;
a.x = jx ;
a.y = jy ;
used[a.x][a.y] = 1 ;
a.time1 = 0 ;
q.push(a) ;
while(!q.empty())
{
a = q.front() ;
if(a.x == 0 || a.x == n - 1 || a.y == 0 || a.y == m - 1)
{
ans = a.time1 + 1 ;
break ;
}
q.pop() ;
for(i = 0 ; i < 4 ; i ++)
{
x1 = a.x + row[i] ;
y1 = a.y + col[i] ;
if(x1 >= 0 && x1 < n && y1 >= 0 && y1 < m
&& used[x1][y1] == 0
&& map1[x1][y1] == '.' && a.time1 + 1 < ftime1[x1][y1])
{
used[x1][y1] = 1 ;
b.x = x1 ;
b.y = y1 ;
b.time1 = a.time1 + 1 ;
q.push(b) ;
}
}
}
}
int main()
{
int i , j ;
int t ;
char s[1005] ;
scanf("%d" , &t) ;
while(t--)
{
scanf("%d%d" , &n , &m) ;
memset(ftime1 , inf , sizeof(ftime1)) ;
for(i = 0 ; i < n ; i ++)
{
scanf("%s" , map1[i]) ;
for(j = 0 ; j < m ; j ++)
{
//疑惑2 scanf("%s" , map1[i]) ;
//换成了 scanf("%s" , s) ;for(j = 0 ; j < m ; j ++) map1[i][j] = s[j]之后就不行了
//之前用后者是可以的
if(map1[i][j] == 'J')
{
jx = i ;
jy = j ;
}
else if(map1[i][j] == 'F')
{
fx = i ;
fy = j ;
fbfs() ;
}
}
}
ans = 0 ;
bfs() ;
if(!ans)
printf("IMPOSSIBLE\n") ;
else
printf("%d\n" , ans) ;
}
}