Fire! UVA - 11624 bfs

1 篇文章 0 订阅

一、内容

题目描述

乔在迷宫中工作。不幸的是,迷宫的一部分着火了,迷宫的主人没有制定火灾的逃跑计划。请帮助乔逃离迷宫。根据乔在迷宫中的位置以及迷宫的哪个方块着火,你必须确定火焰烧到他之前,乔是否可以离开迷宫,如果能离开他能跑多快。
乔和火每分钟移动一个方格,上、下、左、右,四个方向中的一个。火势向四个方向同时蔓延。乔可以从迷宫的任何一个边界逃离迷宫。无论是乔还是火都不会到达有墙的位置。

输入

第一行输入包含一个整数,即测试次数
每个测试用例的第一行包含两个
整数R和C,用空格分隔,1≤R,C≤1000
下面R行中,每一行都包含C个字符,以及每个字符是以下之一:
# 代表墙
. 代表空地,火和乔是可通行的
J 乔在迷宫中最初的位置,火和乔是可通行的
F 代表火
在每组测试中只有一个J

输出

对于每个测试用例,如果在火蔓延的时候烧到了乔,则乔无法逃出迷宫,输出'IMPOSSIBLE'如果乔能逃出迷宫,则输出乔最快可以在几分钟内安全逃出迷宫,每组输出占一行

样例输入

2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F

样例输出

3
IMPOSSIBLE

二、思路

  • 用2个队列分别更新J的状态和火的状态,每秒钟将各自队列里面的节点全部更新完
  • 先更新J的位置,再更新火的状态,同一秒中J先走,火再蔓延

三、代码

#include <cstdio>
#include <iostream>
#include <queue> 
#include <cstring>
using namespace std;
const int N = 1005;
int t, n, m, vis[N][N];
char g[N][N];
int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};
struct node {
	int x, y;
	node(int x, int y): x(x), y(y){}
}; 
void bfs() {
	queue<node> jq; //J所在的点的队列 
	queue<node> fq; //着火点的队列 
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (g[i][j] == 'J') {
				jq.push(node(i, j));
				vis[i][j] = 1;				
			} else if (g[i][j] == 'F') {
				fq.push(node(i, j));
				g[i][j] = '#';//代表不可走 
			}
		} 
	} 	
	int step = 0; 
	int cnt= 0;
	while (jq.size()) {
		step++; //每秒中更新队列里面的所有点
		//J先跑 火再蔓延 
		for (int i = 0, j = jq.size(); i < j; i++) {
			node t = jq.front();
			jq.pop();
			//表明这个点被火给蔓延了不能走了  因为是人先走,火再蔓延 
			if (g[t.x][t.y] == '#') continue; 
			for (int k = 0; k < 4; k++) {
				int fx = t.x + dx[k];
				int fy = t.y + dy[k];
				if (fx >= 0 && fy >= 0 && fx < n &&fy < m) {
					//表明下个点可走入队 
					if (g[fx][fy] != '#' && !vis[fx][fy]) {
						jq.push(node(fx, fy));
						vis[fx][fy] = 1;
					}
				} else {
					//代表走出了边界
					printf("%d\n", step);
					return; 
				}
			} 
		}
		//火蔓延
		for (int i = 0, j = fq.size(); i < j; i++) {
			node t = fq.front();
			fq.pop();
			for (int k = 0; k < 4; k++) {
				int fx = t.x + dx[k];
				int fy = t.y + dy[k];
				if (fx >= 0 && fy >= 0 && fx < n && fy < m && g[fx][fy] != '#') {
					fq.push(node(fx, fy));
					g[fx][fy] = '#';
				}
			} 
		}		
	}
	printf("IMPOSSIBLE\n");
}

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &m);
		for (int i = 0; i < n; i++) {
			scanf("%s", g[i]);
		}
 		bfs();
 		memset(vis, 0, sizeof vis);
	}
 	return 0;
} 
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值