fzu 2150 Fire Game

fzu 2150 Fire Game

题目大意:
给出一个m*n的图,‘#’表示草坪,‘ . ’表示空地,然后可以选择在任意的两个草坪格子点火,火每 1 s会向周围四个格子扩散,问选择那两个点使得燃烧所有的草坪花费时间最小?

具体思路:
数据范围较小,直接枚举两点选择的任意情况,分别进行bfs。取最优解就行
详细:
枚举两个人可能选的坐标情况,作为不同的初始状态
对每个初始状态进行bfs搜索,得到木板上的每块草地被烧完的时间
其中烧完杯子耗时最久的时间就是总时间
然后根据此初始状态的耗时去更新答案
得到所有初始状态中耗时最小的时间
若无法更新得到,则输出-1

因为fzu题目失效,所以代码没有测试过。
更新:
FZU又可以提交了,提交完发现代码有点错误,已更正(GNU C++提交)。
注意:Case %d: %d\n 冒号后面有空格,并且Case首字母大写,贡献了PE…
还有queue > q;两个> >中间要有空格,否则编译错误,我是vs2017调的,没报错,提交就报错了,感谢博友指出。

具体代码:

#include
#include
#include
#include

using namespace std;
const int INF = 1e5;
int step[4][2] = {
      {
     1,0},{
     -1,0},{
     0,1},{
     0,-1} };
int board[11][11];
int cost[11][11]; //表示每块草地烧完的时间
int visit[11][11];	//表示草地是否烧过
int ans =INF;
int m, n;

void get_ans()
{
     
	int res = -1;
	for (int i = 0; i < m; i++)
	{
     
		for (int j = 0; j < n; j++)
		{
     
			if (board[i][j] && !visit[i][j]) {
     
				return;
			}
			//以烧完草地时间最大的作为总时间
			if (board[i][j] && cost[i][j] > res)res = cost[i][j];
		}
	}
	if (res < ans)ans = res;
}
void bfs(int x1,int y1,int x2,int y2)
{
     
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			cost[i][j] = -1, visit[i][j] = 0;
	queue<pair<int, int> > q;
	q.push(pair<int, int>(x1, y1));
	visit[x1][y1] = 1;
	cost[x1][y1] = 0;
	if (!visit[x2][y2]) {
     
		q.push(pair<int, int>(x2, y2)), cost[x2][y2] = 0;
		visit[x2][y2] = 1;
	}
	while (!q.empty())
	{
     
		pair<int, int> t = q.front();
		q.pop();		
		for (int i = 0; i < 4; i++)
		{
     
			int x = t.first, y = t.second;
			x += step[i][0], y += step[i][1];
			if (x >= 0 && x < m &&y >= 0 && y < n && !visit[x][y] && board[x][y]) {
     
				visit[x][y] = 1;
				cost[x][y] = cost[t.first][t.second] + 1;
				q.push(pair<int, int>(x, y));
			}
		}
	}
	get_ans();	//计算该状态下的结果,更新答案
}
int main()
{
     
	int t;
	cin >> t;
	for (int k = 1; k <= t;k++)
	{
     
		cin >> m >> n;
		for (int i = 0; i < m; i++)
		{
     
			string s;
			cin >> s;
			for (int j = 0; j < n; j++)
			{
     
				if(s[j]=='#')board[i][j] = 1;
				else board[i][j] = 0;
			}
		}
		//init();	//初始化所有状态的最少时间
		for (int i = 0; i < m  ; i++)
			for (int j = 0; j < n  ; j++)
				for (int p = 0; p < m ; p++)
					for (int q = 0; q < n  ; q++)
						if (board[i][j] && board[p][q]) {
     
							//cnt[i][j][p][q] = INF;
							bfs(i, j, p, q);
							
						}
		if(ans!=INF)printf("Case %d: %d\n", k, ans);
		else printf("Case %d: -1\n", k);
		ans = INF;
	}  
	
	return 0;
}

你可能感兴趣的:(OJ题解,bfs,&,dfs)