Codeforces 1365D Solve The Maze
算法讨论
可以看到如果没有好人无脑"Yes",如果一个G和一个B相邻,或者有好人的情况下,一个G和 ( n , m ) (n,m) (n,m)这个cell相邻,那么必然是"No"了,之后就看每个G是否能到达 ( n , m ) (n,m) (n,m),最后我的做法是首先特判每个B,看他的周围能否用围墙围上,之后如果都能围上的话,那么就得特判是不是某些G去 ( n , m ) (n,m) (n,m)的路被封住了,假设如果都能到达的情况下,那么这些G就在一个那种类似于"油田灌溉"那种在一个油田中,也就是一个bfs就能将所有G连接的话,那么就绝对可以达到to satisfy the given conditions.
一个小trick
可以将最后一个 ( n , m ) (n,m) (n,m)特殊处理为G,这样可能条件会写少点
算法实现
const int N=55;
int n,m,nx[]={0,1,0,-1},ny[]={1,0,-1,0},num;
string mapp[N];
bool init(int x,int y)
{
rep(i,0,3){
int nnx=x+nx[i],nny=y+ny[i];
if(nnx>=0&&nnx<n&&nny>=0&&nny<m){
if(mapp[nnx][nny]=='G')return false;
else if(mapp[nnx][nny]=='B')continue;
else mapp[nnx][nny]='#';
}
}
return true;
}
bool used[N][N];
bool safe(int x,int y){return x>=0&&x<n&&y>=0&&y<m&&mapp[x][y]!='#'&&!used[x][y]?true:false;}
bool bfs(int bx,int by)
{
mm(used,false);
queue<pair<int,int>>q;
q.push({bx,by});
used[bx][by]=true;
int cnt=0;
while(!q.empty()){
int cx=q.front().first,cy=q.front().second;
q.pop();
if(mapp[cx][cy]=='G')cnt++;
rep(i,0,3){
int nnx=cx+nx[i],nny=cy+ny[i];
if(safe(nnx,nny))q.push({nnx,nny}),used[nnx][nny]=true;
}
}
return cnt==num+1?true:false;
}
int main()
{
rush(){
cin>>n>>m;
rep(i,0,n-1)cin>>mapp[i];
num=0;
rep(i,0,n-1)rep(j,0,m-1)if(mapp[i][j]=='G')num++;
mapp[n-1][m-1]='G';
bool flag=true;
rep(i,0,n-1){
rep(j,0,m-1){
if(mapp[i][j]=='B'){
flag=init(i,j);
if(!flag)break;
}
}
if(!flag)break;
}
bool sus=false;
if(flag){
rep(i,0,n-1){
rep(j,0,m-1){
if(mapp[i][j]=='G'){
flag=bfs(i,j);
sus=true;
break;
}
}
if(sus)break;
}
}
cout<<(flag||!num?"Yes":"No")<<endl;
}
return 0;
}