Codeforces 1365D


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;
}

原文地址:https://www.cnblogs.com/stelayuri/p/13063866.html