1. 程式人生 > 實用技巧 >Fire!

Fire!

Fire!

Fire!

這題真挺磨我心態的...知道是bfs但就是莫名其妙出問題

題目大意:給定一系列火源,牆,人的位置。如果人能比火勢先走到邊上即可成功逃脫,問如果可以的話,求最短時間。

坑點:一系列火源。最開始傻傻的以為有多少火源就得bfs多少次,後面發現將初始點全部放進佇列裡,得到的結果也是最短的。

隨便學了下結構體的建構函式,以後寫這些可能會少個兩三行吧。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;

int mod = 9973;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 10;

int T, a, b;
struct node
{
	int x, y, cnt;
	node(int x, int y, int cnt) : x(x), y(y), cnt(cnt){};//兩個建構函式,如果只寫了這個,那麼直接node x;是會報錯的,所以要寫沒引數的建構函式
	node() : x(), y(), cnt(){};
};
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
vector<node> v;	//vector一定要記得清空啊
char Map[maxn][maxn];
int vis[maxn][maxn];
int Fres[maxn][maxn];//火源的最短時間記錄
int Jres[maxn][maxn];//人的最短時間記錄

int legal(node x)
{
	if (x.x >= b || x.x < 0 || x.y >= a || x.y < 0)
		return 0;
	return 1;
}

void Fbfs()
{
	queue<node> q;
	for (int i = 0; i < v.size(); i++)
	{
		q.push(v[i]);
		vis[v[i].y][v[i].x] = 1;
		Fres[v[i].y][v[i].x] = 0;
	}
	node tem, t;
	while (!q.empty())
	{
		t = q.front();
		q.pop();
		tem.cnt = t.cnt + 1;
		for (int i = 0; i < 4; i++)
		{
			tem.x = t.x + dx[i];
			tem.y = t.y + dy[i];
			if (legal(tem) && !vis[tem.y][tem.x] && Map[tem.y][tem.x] != '#')
			{
				q.push(tem);
				vis[tem.y][tem.x] = 1;
				Fres[tem.y][tem.x] = tem.cnt;
			}
		}
	}
}
void Jbfs(node x)
{
	vis[x.y][x.x] = 1;
	queue<node> q;
	node tem;
	Jres[x.y][x.x] = 0;
	q.push(x);
	while (!q.empty())
	{
		x = q.front();
		q.pop();
		tem.cnt = x.cnt + 1;
		for (int i = 0; i < 4; i++)
		{
			tem.x = x.x + dx[i];
			tem.y = x.y + dy[i];
			if (legal(tem) && !vis[tem.y][tem.x] && Map[tem.y][tem.x] != '#')
			{
				q.push(tem);
				vis[tem.y][tem.x] = 1;
				Jres[tem.y][tem.x] = tem.cnt;
			}
		}
	}
}

void init()
{
	v.clear();
	memset(Map, 0, sizeof(Map));
	memset(vis, 0, sizeof(vis));
	for (int i = 0; i < a; i++)
		for (int j = 0; j < b; j++)
			Fres[i][j] = Jres[i][j] = INF;
}

int main()
{

	cin >> T;
	while (T--)
	{
		node J;
		cin >> a >> b;
		init();

		for (int i = 0; i < a; i++)
			cin >> Map[i];
		for (int i = 0; i < a; i++)
		{
			for (int j = 0; j < b; j++)
			{
				if (Map[i][j] == 'J')
					J.x = j, J.y = i, J.cnt = 0, Jres[i][j] = 0;
				if (Map[i][j] == 'F')
				{
					v.push_back(node(j, i, 0));
					Fres[i][j] = 0;
				}
				if (Map[i][j] == '#')
					Fres[i][j] = INF, Jres[i][j] = INF;
			}
		}
		Jbfs(J);
		memset(vis, 0, sizeof(vis));
		Fbfs();
		int res;
		res = INF;

		/*for (int i = 0; i < a; i++)	//列印一下方便找錯
		{
			for (int j = 0; j < b; j++)
				cout << setw(16) << Fres[i][j];
			cout << endl;
		}
		cout << endl;
		for (int i = 0; i < a; i++)
		{
			for (int j = 0; j < b; j++)
				cout << setw(16) << Jres[i][j];
			cout << endl;
		}*/
		for (int i = 0; i < b; i++)
		{
			if (Fres[0][i] > Jres[0][i])
				res = min(res, Jres[0][i]);
			if (Fres[a - 1][i] > Jres[a - 1][i])
				res = min(res, Jres[a - 1][i]);
		}
		for (int i = 0; i < a; i++)
		{
			if (Fres[i][0] > Jres[i][0])
				res = min(res, Jres[i][0]);
			if (Fres[i][b - 1] > Jres[i][b - 1])
				res = min(res, Jres[i][b - 1]);
		}

		if (res != INF)
			cout << res + 1 << endl;
		else
			cout << "IMPOSSIBLE" << endl;
	}
	return 0;
}