UVa 11624 Fire!(BFS)

本文介绍了一种使用两次广度优先搜索(BFS)来解决火灾中人物(Joe)逃生路径的问题。首先通过BFS预处理出火焰蔓延的时间,然后再次使用BFS找出人物能够逃出建筑物的最短时间。

首先预处理出每个位置被大火烧到的时间,这个也是用bfs计算火的路径。

然后再正常对Joe逃跑路径bfs。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 1005
#include <queue>
int R,C;
int F[maxn][maxn];
char M[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};

struct node{
	int x,y,t;
	node(){}
	node(int x,int y,int t):x(x),y(y),t(t){}
};

bool C1(int x,int y){
	if(x>=0&&x<R&&y>=0&&y<C&&!vis[x][y]) return 1;
	return 0;
}

bool C2(int x,int y,int t){
	if(x<0||x>=R||y<0||y>=C||vis[x][y]) return 0;
	else if(F[x][y]!=-1&&F[x][y]<=t) return 0;
	return 1;
}

bool OK(int x,int y){
	if(x==0||y==0||x==R-1||y==C-1)
		return 1;
	return 0;
}

void init(){
	memset(vis,0,sizeof(vis));
	memset(F,-1,sizeof(F));
	queue<node> Q;
	for(int i=0;i<R;i++){
		for(int j=0;j<C;j++){
			if(M[i][j]=='F'){
				Q.push(node(i,j,0));
				vis[i][j]=1;
				F[i][j]=0;
			}
			if(M[i][j]=='#') vis[i][j]=1;
		}
	}
	while(!Q.empty()){
		node cur=Q.front();
		Q.pop();
		for(int i=0;i<4;i++){
			int tx=cur.x+dir[i][0];
			int ty=cur.y+dir[i][1];
			if(C1(tx,ty)){
				Q.push(node(tx,ty,cur.t+1));
				F[tx][ty]=cur.t+1;
				vis[tx][ty]=1;
			}
		}
	}
	memset(vis,0,sizeof(vis));
	for(int i=0;i<R;i++){
		for(int j=0;j<C;j++){
			if(M[i][j]=='#') vis[i][j]=1;
		}
	}
}

int bfs(int x,int y){
	queue<node> Q;
	Q.push(node(x,y,0));
	if(OK(x,y)){
		return 0;
	}
	vis[x][y]=1;
	while(!Q.empty()){
		node cur=Q.front();
		Q.pop();
		for(int i=0;i<4;i++){
			int tx=cur.x+dir[i][0];
			int ty=cur.y+dir[i][1];
			if(C2(tx,ty,cur.t+1)){
				if(OK(tx,ty)) return cur.t+1;
				Q.push(node(tx,ty,cur.t+1));
				vis[tx][ty]=1;
			}
		}
	}
	return -1;
}

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&R,&C);
		for(int i=0;i<R;i++){
			scanf("%s",M[i]);
		}
		init();
		int res=-1;
		for(int i=0;i<R;i++){
			for(int j=0;j<C;j++){
				if(M[i][j]=='J'){
					res=bfs(i,j);
					break;
				}
			}
		}
		if(res==-1) printf("IMPOSSIBLE\n");
		else printf("%d\n",res+1);
	}
	return 0;
}
/*
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
*/

### 算法竞赛平台 当前主流的算法竞赛平台包括 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、付费专栏及课程。

余额充值