ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

kuangbin专题 专题一 简单搜索 Fire! UVA - 11624

2019-07-08 11:07:08  阅读:290  来源: 互联网

标签:tmp 专题 Fire kuangbin int que Joe dx dy


Fire! UVA - 11624

题目链接:https://vjudge.net/problem/UVA-11624

题意:一个迷宫,可能有一个或者多个地方着火了,每过1个时间消耗,火会向四周蔓延,问Joe能不能逃出迷宫,只要走出迷宫边界就算逃出,火和Joe都不能透过墙。

思路:人和火源分别跑bfs,人一张地图,火源一张地图,跑各自能到达点的时间,火源可能有多个,最后只需要判断迷宫的四个边中人和火源的时间消耗来得出最小答案,出不去输出“IMPOSSIBLE”,思路比较简单,代码稍微复杂点。

#include <iostream>
#include <cstring>
#include<vector>
#include<string>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

#define inf (1LL << 31) - 1
#define rep(i,j,k) for(int i = (j); i <= (k); i++)
#define rep__(i,j,k) for(int i = (j); i < (k); i++)
#define per(i,j,k) for(int i = (j); i >= (k); i--)
#define per__(i,j,k) for(int i = (j); i > (k); i--)

const int N = 1010;
int mv_x[] = { 0, 0, -1, 1 };
int mv_y[] = { 1, -1, 0, 0 };
char mp[N][N];
int Fire[N][N]; //火
bool vis[N][N];
int x[N];  //火源的x
int y[N];  //火源的y
int l;     //火源的个数
int Joe[N][N];  //Joe
int n, m;
int pi, pj; //Joe的坐标

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

inline void init(){
	rep(i, 1, n) rep(j, 1, m){
		Joe[i][j] = 0;
		Fire[i][j] = inf;
	}
}

inline void input(){

	l = 0;
	rep(i, 1, n) rep(j, 1, m){
		cin >> mp[i][j];
		
		//记录每个火源
		if (mp[i][j] == 'J') pi = i, pj = j;
		else if (mp[i][j] == 'F') x[l] = i, y[l++] = j;
	}
}

inline bool check(int x, int y){
	return x >= 1 && x <= n && y >= 1 && y <= m;
}

void bfs_p(){

	queue<node> que;
	Joe[pi][pj] = 1;
	que.push(node{ pi, pj, 1 });

	while (!que.empty()){

		node tmp = que.front();
		que.pop();
		rep__(p, 0, 4){

			int dx = tmp.x + mv_x[p];
			int dy = tmp.y + mv_y[p];

			if (check(dx, dy) && !Joe[dx][dy] && mp[dx][dy] != '#'){
				Joe[dx][dy] = tmp.v + 1;
				que.push(node{ dx, dy, tmp.v + 1 });
			}
		}
	}
}

void bfs_f(int fi, int fj){

	rep(i, 1, n) rep(j, 1, m) vis[i][j] = 0;
	queue<node> que;

	Fire[fi][fj] = 1;
	vis[fi][fj] = true;
	que.push(node{ fi, fj, 1 });

	while (!que.empty()){

		node tmp = que.front();
		que.pop();
		rep__(p, 0, 4){

			int dx = tmp.x + mv_x[p];
			int dy = tmp.y + mv_y[p];

			if (check(dx, dy) && !vis[dx][dy] && mp[dx][dy] != '#'){
				vis[dx][dy] = true;

				if (tmp.v + 1 < Fire[dx][dy])  //比较与之前的火源,哪个最先烧到这个点
					Fire[dx][dy] = tmp.v + 1, que.push(node{ dx, dy, tmp.v + 1 });

				//	cout <<  "Fire[][] " <<  Fire[dx][dy] << endl;

			}
		}
	}


}

void search_fire(){

	rep__(i, 0, l){
		bfs_f(x[i], y[i]);
	}
}

void get_ans(){

	int ans = inf;

	//先把Fire地图所有的inf,也就是无法到达的点赋值为0,方便比较
	rep(i, 1, n) rep(j, 1, m) if (Fire[i][j] == inf) Fire[i][j] = 0;

	//一种情况,Joe到达某点时间比Fire短,
	//另一个情况,可能Fire到达不了那个点,于是Fire[x][y] == 0,所有有个特殊判断 Fire[x][y] == 0
	
	//下面就是四个边界情况了
	rep(i, 1, n){
		if (i == 1 || i == n){
			rep(j, 1, m){
				if (Joe[i][j] < Fire[i][j] || (Fire[i][j] == 0 && Joe[i][j] != 0)) 
					ans = min(ans, Joe[i][j]);
			}
		}
		else {
			if (Joe[i][1] < Fire[i][1] || (Fire[i][1] == 0 && Joe[i][1] != 0)) 
				ans = min(ans, Joe[i][1]);

			if (Joe[i][m] < Fire[i][m] || (Fire[i][m] == 0 && Joe[i][m] != 0)) 
				ans = min(ans, Joe[i][m]);
		}
	}

	if (ans == inf) cout << "IMPOSSIBLE" << endl;
	else cout << ans << endl;
}

int main(){

	ios::sync_with_stdio(false);
	cin.tie(0);

	int T;
	cin >> T;

	rep(i, 1, T){

		cin >> n >> m;
		init(); //初始化
		input();  //输入
		bfs_p();  //Joe的bfs
		search_fire();  //所有火源的bfs
		get_ans();  //得到答案
	}


	return 0;
}

标签:tmp,专题,Fire,kuangbin,int,que,Joe,dx,dy
来源: https://blog.csdn.net/SSummerzz/article/details/95044772

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有