UVA11624 Fire!

诡异的传送门

POJ破二百什么的计划,暂时先放下吧,师父已经决定带我刷题,还有什么破事儿。

从uva入手好了,做了佳哥书上第一道题。给一个迷宫,有障碍,还有危险,危险还带扩展的,这道题看上去就是一个没思路,但是仔细想想,危险带扩展的话,我们可以把每一个节点被扩展的时间预处理出来,然后呢,然后直接一个广搜搞定它……

#include 
#include 
#include 
#include 
using namespace std;
const int INF = 0x7fffffff;
const int N = 1111;
char s[N][N];
int g[N][N], r, c, f[N][N];
const int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
struct nod{
	int x, y;
}S;
queue F;
void init(){
	memset(g, -1, sizeof(g));
	memset(f, -1, sizeof(f));
	for (int i = 0; i < r; i++)
		for (int j = 0; j < c; j++){
			if (s[i][j] == 'J'){
				S.x = i; S.y = j;
			}
			if (s[i][j] == 'F'){
				f[i][j] = 1;
				nod t; t.x = i; t.y = j;
				F.push(t);
			}
        }
}
bool getgoal(int x, int y){
	return x >= 0 && x < r && y >= 0 && y < c;
}
void gettime(){
	nod u, v;
	while(!F.empty()){
		u = F.front();
		F.pop();
		int x = u.x, y = u.y;
		for (int i = 0; i < 4; i++){
			int xx = x + dir[i][0];
			int yy = y + dir[i][1];
			if (!getgoal(xx, yy) || s[xx][yy] == '#') continue;
			if (f[xx][yy] == -1 || f[xx][yy] > f[x][y] + 1){
				f[xx][yy] = f[x][y] + 1;
				v.x = xx; v.y = yy;
				F.push(v);
			}
		}
	}
}
void escape(){
	queue Q;
	g[S.x][S.y] = 1;
	Q.push(S);
	nod u, v;
	while(!Q.empty()){
		u = Q.front();
		Q.pop();
		int x = u.x, y = u.y;
		for (int i = 0; i < 4; i++){
			int xx = x + dir[i][0];
			int yy = y + dir[i][1];
			if (!getgoal(xx, yy) || s[xx][yy] == '#') continue;
			if (s[xx][yy] == '.' && f[xx][yy] > 0 && g[x][y] + 1 >= f[xx][yy]) continue;
			if (g[xx][yy] > g[x][y] + 1 || g[xx][yy] == -1){
				g[xx][yy] = g[x][y] + 1;
				v.x = xx; v.y = yy;
				Q.push(v);
			}
		}
	}
}
int main(){
	int cs;
	scanf("%d", &cs);
	while(cs--){
		scanf("%d%d", &r, &c);
		for (int i = 0; i < r; i++)
			scanf("%s", s[i]);
		init();
		gettime();
		escape();
		int ans = INF;
		for (int i = 0; i < c; i++){
			if (g[0][i] > 0) ans = min(g[0][i], ans);
			if (g[r - 1][i] > 0) ans = min(g[r - 1][i], ans);
		}
		for (int i = 0; i < r; i++){
			if (g[i][0] > 0) ans = min(g[i][0], ans);
			if (g[i][c - 1] > 0) ans = min(g[i][c - 1], ans);
		}
		if (ans == INF) puts("IMPOSSIBLE");
		else printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(搜索)