D. Solve The Maze
题解
考虑利用边界和墙来封锁坏人,封锁圈越大,好人的空间就越小。如果一个封锁圈是合理的,那么比他小的封锁圈也一定是合理的,无限小直到包裹坏人的四周
所以贪心地在坏人四周放墙,如果放的过周围有好人在周围,或者有好人但是把终点放了,或者从终点出发无法到达所有的好人(从多元深搜变成了单源广搜)
code
#include<bits/stdc++.h>
using namespace std;
int n,m;
char s[55][55];
int xx[4]={1,0,-1,0},yy[4]={0,-1,0,1};
struct node
{
    int x,y;
};
int check()
{
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(s[i][j]=='B')
            {
                for(int k=0;k<4;k++)
                {
                    int x1=i+xx[k],y1=j+yy[k];
                    if(x1>0&&x1<=n&&y1>0&&y1<=m)
                    {
                        if(s[x1][y1]=='G') return 0;
                        if(s[x1][y1]=='.') s[x1][y1]='#';
                    }
                }
            }
            if(s[i][j]=='G') sum++;
        }
    }
    if(sum&&s[n][m]=='#') return 0;
    int vis[55][55]={0};
    queue<node> q;
    q.push({n,m});
    vis[n][m]=1;
    while(q.size())
    {
        int x=q.front().x,y=q.front().y;
        q.pop();
        if(s[x][y]=='G') sum--;
        for(int i=0;i<4;i++)
        {
            int x1=x+xx[i],y1=y+yy[i];
            if(x1>0&&x1<=n&&y1>0&&y1<=m&&!vis[x1][y1]&&s[x1][y1]!='#')
            {
                q.push({x1,y1});
                vis[x1][y1]=1;
            }
        }
    }
    return !sum;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++) cin>>s[i][j];
        }
        if(check())puts("YES");
        else puts("NO");
    }
    return 0;
}
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号