Loading...

搜索小练#9后续

给出完整的AC代码

这个题只需要写一个队列....

枚举两个人可能选的坐标情况,作为不同的初始状态

对每个初始状态进行bfs搜索,得到木板上的每块草地被烧完的时间

其中烧完杯子耗时最久的时间就是总时间

然后根据此初始状态的耗时去更新答案

得到所有初始状态中耗时最小的时间

若无法更新得到,则输出-1

注意标点符号

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int N = 66, INF = 214748364;

int T, n, m, k, res;
int a[N][N], v[N][N], cost[N][N];

int dx[N] = {0, 0, 1, -1};
int dy[N] = {1, -1, 0, 0};

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

inline void getsum () {
	int tmp = -1;
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= m; ++ j) {
			if (a[i][j] && !v[i][j]) return;
			if (a[i][j] && cost[i][j] > tmp)
				tmp = cost[i][j];
		}
	if (tmp < res) res = tmp;
}

inline void bfs (int nx, int ny, int s, int t) {
	memset (v, 0, sizeof v);
	memset (cost, -1, sizeof cost);
	queue<node>q;
	v[nx][ny] = 1, cost[nx][ny] = 0;
	q.push(node(nx, ny));
	if (!v[s][t]) {
		v[s][t] = 1;
		cost[s][t] = 0;
		q.push(node(s, t));
	}
	while (q.size()) {
		node tmp = q.front(); q.pop();
		for (int i = 0; i < 4; ++ i) {
			int curx = tmp.x+dx[i], cury = tmp.y+dy[i];
			if ((curx < 1) || (curx > n) || (cury < 1) || (cury > m)) continue;
			if (!v[curx][cury] && a[curx][cury]) {
				v[curx][cury] = 1;
				cost[curx][cury] = cost[tmp.x][tmp.y]+1;
				q.push(node(curx, cury));
			}
		}
	}
	getsum();
}

int main () {
	char ch[N];
	scanf ("%d", &T);
	while (T --> 0) {
		++ k; res = INF;
		scanf ("%d%d", &n, &m);
		for (int i = 1; i <= n; ++ i) {
			scanf ("%s", ch+1);
			for (int j = 1; j <= m; ++ j)
				a[i][j] = (ch[j] == '#') ? 1 : 0;
		}
		for (int i = 1; i <= n; ++ i)
			for (int j = 1; j <= m; ++ j)
				for (int ni = 1; ni <= n; ++ ni)
					for (int nj = 1; nj <= m; ++ nj)
						if (a[i][j] && a[ni][nj])
							bfs (i, j, ni, nj);
		if (res != INF) printf ("Case %d: %d\n", k, res);
		else printf ("Case %d: -1\n", k);
	}
	return 0;
}
posted @ 2020-07-23 14:16  Youngore  阅读(68)  评论(0)    收藏  举报