[bfs] UVA11624-Fire!
2015-07-27 17:07
429 查看
11624 Fire!
Joe works in a maze. Unfortunately, portions of the maze have caught
on fire, and the owner of the maze neglected to create a fire escape plan.
Help Joe escape the maze.
Given Joe’s location in the maze and which squares of the maze are
on fire, you must determine whether Joe can exit the maze before the
fire reaches him, and how fast he can do it.
Joe and the fire each move one square per minute, vertically or
horizontally (not diagonally). The fire spreads all four directions from
each square that is on fire. Joe may exit the maze from any square
that borders the edge of the maze. Neither Joe nor the fire may enter
a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test cases
to follow. The first line of each test case contains the two integers R
and C, separated by spaces, with 1 ≤ R, C ≤ 1000. The following R lines of the test case each contain
one row of the maze. Each of these lines contains exactly C characters, and each of these characters is
one of:
• #, a wall
• ., a passable square
• J, Joe’s initial position in the maze, which is a passable square
• F, a square that is on fire
There will be exactly one J in each test case.
Output
For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the
fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
一个迷宫,其中有部分点着火了,火势上下左右四个方向每秒蔓延一个格子,并且每个点一旦着火不会熄灭。现在J在迷宫中的一个位置,问J是否能在火势把路封住以前逃到边界?如果可以输出逃出去的最短时间,如果不可以输出impossible。
好复杂的bfs,原来想对火和人做分别bfs,利用两个队列,一个存储人的状态,一个存储火的状态,但是这样修改以后整个状态不容易表示出来。
后来发现,火的扩散过程和人的行动两个过程是用相同的形式,所以可以用一个队列来存储两种状态,设置一个标志量判断是火还是人,先更新火的节点,再更新人的节点,按照顺序入队出队即可。
Joe works in a maze. Unfortunately, portions of the maze have caught
on fire, and the owner of the maze neglected to create a fire escape plan.
Help Joe escape the maze.
Given Joe’s location in the maze and which squares of the maze are
on fire, you must determine whether Joe can exit the maze before the
fire reaches him, and how fast he can do it.
Joe and the fire each move one square per minute, vertically or
horizontally (not diagonally). The fire spreads all four directions from
each square that is on fire. Joe may exit the maze from any square
that borders the edge of the maze. Neither Joe nor the fire may enter
a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test cases
to follow. The first line of each test case contains the two integers R
and C, separated by spaces, with 1 ≤ R, C ≤ 1000. The following R lines of the test case each contain
one row of the maze. Each of these lines contains exactly C characters, and each of these characters is
one of:
• #, a wall
• ., a passable square
• J, Joe’s initial position in the maze, which is a passable square
• F, a square that is on fire
There will be exactly one J in each test case.
Output
For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the
fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
Sample Input 2 4 4 #### #JF# #..# #..# 3 3 ### #J. #.F Sample Output 3 IMPOSSIBLE
一个迷宫,其中有部分点着火了,火势上下左右四个方向每秒蔓延一个格子,并且每个点一旦着火不会熄灭。现在J在迷宫中的一个位置,问J是否能在火势把路封住以前逃到边界?如果可以输出逃出去的最短时间,如果不可以输出impossible。
好复杂的bfs,原来想对火和人做分别bfs,利用两个队列,一个存储人的状态,一个存储火的状态,但是这样修改以后整个状态不容易表示出来。
后来发现,火的扩散过程和人的行动两个过程是用相同的形式,所以可以用一个队列来存储两种状态,设置一个标志量判断是火还是人,先更新火的节点,再更新人的节点,按照顺序入队出队即可。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; const int MAXN = 1005; int R,C,T; int vis[MAXN][MAXN]; char mat[MAXN][MAXN]; int fx,fy; int dx[]= {1,-1,0,0}; int dy[]= {0,0,1,-1}; struct node { int x,y; int step; bool isfire; }; int bfs() { node a,next; memset(vis,0,sizeof(vis)); queue<node> Q; //"火"先进队列 注意:初始可能有多个位置起火。 for(int i = 0; i < R; i++) { for(int j = 0; j < C; j++) { if (mat[i][j] =='F') { a.x = i,a.y = j; a.step = 0; a.isfire = true; Q.push(a); } } } //人再进队列. next.x = fx,next.y =fy; next.step = 0; next.isfire = false; Q.push(next); while(!Q.empty()) { a = Q.front(); Q.pop(); // printf("fire? %d x:%d y:%d\n",a.isfire,a.x,a.y); // getchar(); if (a.isfire) //对火进行扩展 { for(int i =0; i<4 ;i++) { int nx = a.x + dx[i]; int ny = a.y + dy[i]; // printf("nx : %d, ny:%d\n",nx,ny); if (nx<0||nx>=R || ny<0 ||ny>=C || mat[nx][ny]=='#' ||mat[nx][ny]=='F' ) continue; mat[nx][ny] ='F'; next.x = nx; next.y = ny; next.step = a.step+1; next.isfire = true; Q.push(next); //puts("push"); } } else //对人进行扩展 { // printf("x = %d, y = %d\n",a.x,a.y); for(int i = 0;i<4;i++) { int nx = a.x+dx[i]; int ny = a.y+dy[i]; // printf(" nx = %d, ny = %d\n",nx,ny); if (nx<0 || nx>=R || ny<0 || ny >=C) return a.step+1; if (vis[nx][ny] || mat[nx][ny] =='#' || mat[nx][ny]=='F') continue; vis[nx][ny] = true; next.x = nx; next.y = ny; next.isfire = false; next.step = a.step+1; Q.push(next); } } } return 0; } int main() { // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%d",&R,&C); fx = fy = -1; for(int i =0;i<R;i++) { for(int j = 0;j<C;j++) { cin>>mat[i][j]; if (fx == -1 && mat[i][j] =='J') fx = i,fy = j; } } int ans = bfs(); if (ans) printf("%d\n",ans); else printf("IMPOSSIBLE\n",ans); } return 0; }
相关文章推荐
- 两个日期相差的天数
- 【机房收费系统】上下机
- jedis应用实例
- centos7 mysql数据库安装和配置
- jedis应用实例
- UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
- 使用python求字符串或文件的MD5
- AJAX性能优化方法
- js传值到后台中文乱码解决方法
- Red Hat Enterprise Linux 7(RHEL7)安装64位sde9.3
- java分布式框架-JDF
- android Handler,Looper,Message三者关系
- adb install 流程
- 【cogs58】延绵的山峰【st表】
- 客户端开发--1开发入门
- Complementing a Strand of DNA
- Codeforces Round #298 (Div. 2) D. Handshakes 二分
- Yii2-Redis使用小记 - Cache
- javaWeb web.xml 配置
- easysize的使用方法 (实现控件大小位置随界面变化而有相应的变化,这个变化可以自己设置)