【补题日记】[FZU2150]Fire Game

Pro

FZU2150

Sol

之前做搜索的训练的时候这个题就A了 后来提交kuangbin的题单的时候又T了

发现 原来真的可以随缘AC(逃

然后不得不对这个程序进行优化

优化的地方在于:枚举每一个两个火的时候只需要搜索一个直角三角形就行(而不是n×m)

这样时间就少了一大半

我还试过是不是输入cin太慢 改为scanf和getchar之后时间是一样的

思路不用多说 裸的bfs 但就是细节处理不好容易T

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(int &x) {
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

#define INF 2147483647
struct Node {
	int x , y , t;
};
vector<Node>z;
char map[15][15];
int T , m , n , dx[10] , dy[10] , vis[15][15] , minn , flag , maxx , cas , sz;

void init() {
	z.clear();
	cas++;
	minn = INF;
}

int jud(int x , int y) {
	if(x>=1&&x<=n&&y>=1&&y<=m&&vis[x][y]==0&&map[x][y]=='#')
		return 1;
	return 0;
}

void bfs(int x1 , int y1 , int x2 , int y2) {
	Node s1 , s2;
	s1.x = x1; s1.y = y1; s1.t = 0;
	s2.x = x2; s2.y = y2; s2.t = 0;
	vis[x1][y1] = 1;
	vis[x2][y2] = 1;
	queue<Node>q;
	if(s1.x==s2.x&&s1.y==s2.y)
		q.push(s1);
	else {
		q.push(s1);
		q.push(s2);
	}
	while(!q.empty()) {
		Node u = q.front();
		q.pop();
		for(int i=1; i<=4; i++) {
			Node v;
			int sx = u.x+dx[i] , sy = u.y+dy[i];
			if(jud(sx , sy)) {
				vis[sx][sy] = vis[u.x][u.y] + 1;
				v.x = sx;
				v.y = sy;
				v.t = u.t + 1;
				q.push(v);
			}
		}
	}
}

void check() {
	maxx = -1;
	for(int i=0; i<sz; i++) {
		if(vis[z[i].x][z[i].y]==0) {
			flag = 1;
			return ;
		}
		maxx = max(maxx , vis[z[i].x][z[i].y]-1);		
	}
}

int main() {
//	fin
	dx[1] = -1; dy[1] = 0;
	dx[2] = 1; dy[2] = 0;
	dx[3] = 0; dy[3] = -1;
	dx[4] = 0; dy[4] = 1;
	read(T);
	while(T--) {
		init();
		read(n); read(m);
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++) {
				cin>>map[i][j];
				if(map[i][j]=='#') {
					Node x;
					x.x = i;
					x.y = j;
					z.push_back(x);
				}
			} 
		sz = z.size();
		if(sz==1) {
			printf("Case %d: 0\n",cas);
			continue;
		}
		for(int i=0; i<sz; i++)
			for(int j=i; j<sz; j++) {
				memset(vis , 0 , sizeof(vis));
				flag = 0;
				bfs(z[i].x , z[i].y , z[j].x , z[j].y);
				check();
				if(flag==0)
					minn = min(minn , maxx);					
			}
		if(minn==INF)
			printf("Case %d: -1\n",cas);
		else
			printf("Case %d: %d\n",cas,minn);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cls1277

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值