fzu 2150 Fire Game(BFS)

题目链接:fzu 2150 Fire Game


题目大意:有一块空地上有些草堆‘#’,两个小伙伴想要在这片地上玩耍,然后就要烧掉这些草堆,相邻的草堆可以相互引燃,两个人可以分别选择一块草堆点燃,问说最少需要多少时间才能烧光草堆(每人只能点一次)


解题思路:枚举两个位置同时做为起点,然后BFS,注意有一个坑点就是说草堆的个数少于2的时候,枚举不到两个起点,但是是可以烧光草堆的。


#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 20;
const int dir[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}};

struct point {
	int x, y;
	point() {}
	point(int a, int b) { x = a; y = b; }
};
int l, r, d[N][N], tmp;
char g[N][N];

void init() {
	memset(g, 0, sizeof(g));
	tmp = 0;

	scanf("%d%d%*c", &r, &l);
	
	for (int i = 0; i < r; i++) {
		gets(g[i]);
		for (int j = 0; j < l; j++) if (g[i][j] == '#') tmp++;
	}
}

int bfs(int x1, int y1, int x2, int y2) {
	memset(d, INF, sizeof(d));

	d[x1][y1] = d[x2][y2] = 0;

	point k, c;

	queue<point> q;
	q.push(point(x1, y1));
	q.push(point(x2, y2));

	while ( !q.empty() ) {
		k = q.front(); q.pop();

		for (int i = 0; i < 4; i++) {
			c.x = k.x + dir[i][0]; c.y = k.y + dir[i][1];
			if (c.x < 0 || c.x >= r || c.y < 0 || c.y >= l) continue;
			if (g[c.x][c.y] != '#') continue;

			if (d[c.x][c.y] > d[k.x][k.y] + 1) {
				d[c.x][c.y] = d[k.x][k.y] + 1;
				q.push(c);
			}
		}
	}

	int ans = 0;
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < l; j++) if (g[i][j] == '#') {
			ans = max(ans, d[i][j]);
		}
	}
	return ans;
}


int solve() {
	if (tmp <= 2) return 0;
	int ans = INF;
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < l; j++) if (g[i][j] == '#') {
			for (int k = 0; k < r; k++) {
				for (int t = 0; t < l; t++) {
					if (k == i && t <= j) continue;
					if (g[k][t] == '#') 
						ans = min(ans, bfs(i, j, k, t));
				}
			}
		}
	}
	return ans == INF ? -1 : ans;
}

int main () {
	int cas;
	scanf("%d", &cas);
	for (int i = 1; i <= cas; i++) {
		init();
		printf("Case %d: %d\n", i, solve());
	}
	return 0;
}



你可能感兴趣的:(fzu 2150 Fire Game(BFS))