Codeforces Round #648 (Div. 2) D. Solve The Maze

Codeforces Round #648 (Div. 2) D. Solve The Maze

标签:BFS.

题意:给一个迷宫,‘#’表示墙,‘G’表示好人,’B‘表示坏人,终点在(n,m)。问可否在空地上加上墙,使得所有好人都可以走到终点,所有坏人都无法走到终点。

tips:
A.贪心,考虑在所有坏人周围能加墙的地方加上墙(把坏人围起来)。如果坏人和好人相邻,显然是NO(因为好人所有能去的地方坏人都能去qwq)。
B.如果没有好人,直接输出YES(可以直接把终点堵起来)。【但是注意没有坏人不能直接输出YES,因为好人有可能被墙挡住】。
C.不要对每一个好人跑BFS,这样复杂度太高。因为每个好人如果最后都能到达终点,则从终点开始反向跑BFS,可以经过的好人数目应该就是好人的总数。一次BFS即可。

#include<bits/stdc++.h>
#define m_p make_pair
using namespace std;

int n,m,t,cntgood;
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
vector<pair<int, int> > bad;
vector<pair<int, int> > :: iterator it;
char mp[55][55];

void init(){
	while(!bad.empty())		bad.pop_back();
	cntgood = 0;
}

int bfs(){
	if(mp[n][m] == '#')	return 0;
	int cnt = 0;
	bool vis[55][55] = {false};
	queue<pair<int, int> >q;
	q.push(m_p(n, m));
	while(!q.empty()){
		int xx = q.front().first, yy = q.front().second;	q.pop();
		if(vis[xx][yy])	continue;
		vis[xx][yy] = true;
		if(mp[xx][yy] == 'G')	cnt++;
		for(int k = 0; k < 4; ++k){
			int tx = xx + dir[k][0] , ty = yy + dir[k][1];
			if(tx < 1 || tx > n || ty < 1 || ty > m || mp[tx][ty] == '#')	continue;
			q.push(m_p(tx, ty)); 
		}
	}
	return cnt;
}
void solve(){
	init();
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; ++i){
		getchar();
		for(int j = 1; j <= m; ++j){
			scanf("%c",&mp[i][j]);
			if(mp[i][j] == 'B')	bad.push_back(m_p(i,j)); 
			if(mp[i][j] == 'G')	cntgood++;
		}
	}
	if(!cntgood)	printf("Yes\n");
	else{
		for(it = bad.begin(); it != bad.end(); ++it){
			int x = it->first, y = it->second;
			for(int k = 0; k < 4; ++k){
				int tx = x + dir[k][0] , ty = y + dir[k][1];
				if(tx < 1 || tx > n || ty < 1 || ty > m)	continue;
				if(mp[tx][ty] == 'G'){
					printf("No\n");
					return ;
				}else if(mp[tx][ty] == '.')	mp[tx][ty] = '#';
			}
		}
		(bfs() == cntgood) ? printf("Yes\n") : printf("No\n");
	}
}

int main(){
	scanf("%d",&t);
	while(t--)
		solve();
	return 0;
}


/*bool bfs(int x, int y){			//不要这样bfs,对每个人跑bfs太慢
	bool vis[55][55] = {false};
	queue<pair<int, int> >q;
	q.push(m_p(x, y));
	while(!q.empty()){
		int xx = q.front().first, yy = q.front().second;	q.pop();
		if(xx == n && yy == m)	return true;
		if(vis[xx][yy])	continue;
		vis[xx][yy] = true;
		for(int k = 0; k < 4; ++k){
			int tx = xx + dir[k][0] , ty = yy + dir[k][1];
			if(tx < 1 || tx > n || ty < 1 || ty > m || mp[tx][ty] == '#')	continue;
			q.push(m_p(tx, ty)); 
		}
	}
	return false;
}*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值