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<pair<int, int> > q;两个> >中间要有空格,否则编译错误,我是vs2017调的,没报错,提交就报错了,感谢博友指出。

具体代码:

#include<iostream>
#include<queue>
#include<cstdio>
#include<string>

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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值