UVA 11624 Fire!

在这款迷宫逃脱游戏中,玩家必须帮助Joe在火势蔓延前找到出口。Joe和火势每分钟移动一格,游戏的目标是在火势到达之前找到迷宫的出口。本文详细介绍了游戏规则和算法实现。

Fire!

https://vjudge.net/problem/UVA-11624
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

C++

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int MAXN = 1000 + 5;
const int INF = 0x3f3f3f3f;
char maze[MAXN][MAXN];
bool vis[MAXN][MAXN];
int timeFire[MAXN][MAXN];
int dir[4][2] = {0,1,1,0,0,-1,-1,0};
int n, m;

struct node{
	int x, y, step;
};

queue<node> fire;

bool judge(int x, int y)
{
	return x >= 0 && x < n && y >= 0 && y < m;
}

void bfsFire()
{
	node now, next;
	while(!fire.empty())
	{
		now = fire.front();
		fire.pop();
		for(int i = 0; i < 4; i ++)
		{
			int tx = now.x + dir[i][0];
			int ty = now.y + dir[i][1];
			if(judge(tx, ty) && !vis[tx][ty] && maze[tx][ty] != '#')
			{
				vis[tx][ty] = true;
				timeFire[tx][ty] = timeFire[now.x][now.y] + 1;
				next.x = tx;
				next.y = ty;
				fire.push(next);
			}
		}
	}	
}

void bfs(int x, int y)
{
	memset(vis, false, sizeof(vis));
	queue<node> q;
	node now, next;
	now.x = x;
	now.y = y;
	now.step = 0;
	vis[x][y] = true;
	q.push(now);
	while(!q.empty())
	{
		now = q.front();
		q.pop();
		for(int i = 0; i < 4; i ++)
		{
			int tx = now.x + dir[i][0];
			int ty = now.y + dir[i][1];
			if(tx < 0 || tx >= n || ty < 0 || ty >= m)
			{
				printf("%d\n", now.step + 1);
				return;
			}
			if(!vis[tx][ty] && maze[tx][ty] != '#' && now.step + 1 < timeFire[tx][ty])
			{
				vis[tx][ty] = true;
				next.x = tx;
				next.y = ty;
				next.step = now.step + 1;
				q.push(next);
			}
		}
	}
	printf("IMPOSSIBLE\n");
	return;
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T --)
	{
		int sx, sy; node tmp;
		memset(vis, false, sizeof(vis));
		memset(timeFire, INF, sizeof(timeFire));
		scanf("%d%d", &n, &m);
		getchar();
		for(int i = 0; i < n; i ++)
		{
			for(int j = 0; j < m; j ++)
			{
				scanf("%c", &maze[i][j]);
				if(maze[i][j] == 'J'){
					sx = i; sy = j;
				}
				else if(maze[i][j] == 'F'){
					tmp.x = i;
					tmp.y = j;
					fire.push(tmp);
					vis[i][j] = true;
					timeFire[i][j] = 0;
				}
			}
			getchar();
		}
		bfsFire();
		bfs(sx, sy);
	}
	return 0;
}
### 算法竞赛平台 当前主流的算法竞赛平台包括 Codeforces、AtCoder、TopCoder 和 LeetCode。这些平台不仅提供在线比赛,还拥有丰富的练习题库供选手提升技能[^1]。 Codeforces 是全球范围内最受欢迎的比赛平台之一,定期举办 Div. 1 至 Div. 3 的比赛,并支持多种语言提交代码。 LeetCode 则更注重实际应用能力,适合准备技术面试的同时提高算法水平。它提供了详细的分类标签和企业真题解析功能[^2]。 --- ### 常见题目解析 以下是部分经典题目及其难度分析: #### 动态规划 - **UVA11300 Spreading the Wealth (难度: 5)**:该题涉及经典的动态规划问题,目标是最小化财富分配中的最大差值[^2]。 - **UVA11464 Even Parity (难度: 5)**:通过状态压缩 DP 解决棋盘上的翻转操作问题。 #### 数据结构 - **UVA11995 I Can Guess the Data Structure! (难度: 3)**:判断给定序列是否符合栈、队列或优先队列的行为模式[^2]。 - **UVA11997 K Smallest Sums (难度: 5)**:利用堆优化实现高效的 k 小求解[^2]。 #### 图论 - **UVA11624 Fire! (难度: 5)**:基于 BFS 或 Dijkstra 的最短路径扩展问题,需考虑火势蔓延的影响[^2]。 - **UVA10816 Travel in Desert (难度: 6)**:结合最小生成树与双关键字贪心策略解决复杂图模型下的旅行路线选择[^2]。 --- ### 训练方法建议 1. **制定计划**:按照章节顺序逐步学习《算法竞赛入门经典》等书籍的内容,完成对应章节推荐的经典例题。 2. **专项突破**:针对薄弱环节集中刷题,比如动态规划可以先从简单的一维/二维 DP 开始,再过渡到区间 DP 和状压 DP[^1]。 3. **模拟实战**:参加虚拟比赛(Virtual Contests),严格按照正式比赛时间限制答题,锻炼抗压能力和快速编码技巧。 4. **总结反思**:每次赛后认真阅读官方题解或其他高排名选手分享的经验帖,记录下自己容易忽略的知识点或者错误思路。 ```python def simulate_training(days=30): """ 模拟一个月内的训练安排 """ topics = ["DP", "Graph Theory", "Data Structures"]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值