Codeforces Round #648 (Div. 2) D - Solve The Maze
题意
图中有空白位置'.',有墙'#',有好人'G',有坏人'B',为墙的方块不能行走,只能往上下左右四个方向行走
可以在某些空白位置设置一些墙,使得坏人到达不了点(n,m),好人能够全部到达(n,m)
有可行方案输出Yes,反之输出No
保证点(n,m)一开始是空白的
限制
Time limit per test: 1 second
Memory limit per test: 256 megabytes
- 1≤t≤100
- 1≤n,m≤50
解题思路
最优的方案就是在所有坏人四周直接围上一堵墙,使其不能走出当前位置,且最大程度上不影响其他路线
如果坏人周围就有好人,明显坏人可以跟着好人走到(n,m)点,这种不可行
然后记录原本图中好人的数量cnt,再从点(n,m)开始搜索一次看能找到多少好人,记作cnt2
如果cnt==cnt2
,则好人全部能走到(n,m),反之会有一些好人没法走到
完整程序 (bfs)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
char mp[55][55];
int n,m,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
bool prim(int x,int y)
{
return x>0&&y>0&&x<=n&&y<=m;
}
void solve()
{
int cnt=0,cnt2=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>mp[i]+1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]=='B') //如果找到一个坏人,就在它周围尝试设置墙
{
for(int k=0;k<4;k++)
{
int px=dx[k]+i,py=dy[k]+j;
if(prim(px,py))
{
if(mp[px][py]=='.')
mp[px][py]='#';
else if(mp[px][py]=='G') //坏人周围有好人的情况
{
cout<<"No
";
return;
}
}
}
}
else if(mp[i][j]=='G') //如果是好人,记录数量
cnt++;
}
}
if(mp[n][m]=='#') //坏人周围建完墙后如果把(n,m)也设置成墙了
{
if(cnt==0) //可行方案中一定不能存在好人
cout<<"Yes
";
else
cout<<"No
";
return;
}
queue<P> q;
q.push(P(n,m)); //从(n,m)开始搜索,记录能搜索到的好人数量
mp[n][m]='#';
while(!q.empty())
{
P pd=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int px=dx[i]+pd.first,py=dy[i]+pd.second;
if(prim(px,py)&&mp[px][py]!='#')
{
if(mp[px][py]=='G') //记录能搜索到的好人数量
cnt2++;
q.push(P(px,py));
mp[px][py]='#';
}
}
}
if(cnt==cnt2)
cout<<"Yes
";
else
cout<<"No
";
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--)
solve();
return 0;
}