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

D、Solve The Maze

 

题意:

给你n行m列的一个迷宫,你可以上下左右移动,这个迷宫由一些字符组成,下面说一下这些字符的意思:

“.” 表示空的方格,即可以移动到这个位置

“G”表示这是一个可以到达的好人的牢房

“B”表达这是一个可以到达的坏人的牢房

“#”表示这是一堵墙,不可到达

 

你可以把“.”的方格变成一堵墙“#”。你需要保证在改变完迷宫之后保证好人都可以走到(n,m)点,坏人都不可以走到。如果可以完成输出Yes,否则输出No

 

题解:

特判:

如果好人的牢房和坏人的牢房相邻(相邻就是走一步就可以到达)那么肯定输出No。

 

首先你需要把坏人周围(上下左右)可以移动的地方“.”都设置成墙“#”,这样的话就保证了坏人肯定出不去。因为坏人周围只会出现“.”、“G”、“B”、“#”,出现G的话就直接输出No了

出现B的话那么我们后面枚举到它的时候会把它周围可移动的地方封锁,这样就保证了这两个被完全封锁起来

 

然后从点(n,m)开始bfs,如果能找到所有好人,那么就输出Yes,否则输出No

 

 

代码:

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string>
  5 #include<queue>
  6 #include<deque>
  7 #include<string.h>
  8 #include<map>
  9 #include <iostream>
 10 #include <math.h>
 11 using namespace std;
 12 typedef long long ll;
 13 const int maxn=50+10;
 14 char s[maxn][maxn];
 15 int vis[maxn][maxn],n,m;
 16 struct shudui
 17 {
 18     int x,y;
 19 }str1,str2;
 20 queue<shudui>r;
 21 int p[4][2]={
 22 {1,0},
 23 {-1,0},
 24 {0,1},
 25 {0,-1}
 26 };
 27 int bfs()
 28 {
 29     int num=0;
 30     while(!r.empty())
 31     {
 32         str1=r.front();
 33         r.pop();
 34         if(s[str1.x][str1.y]=='G') ++num;
 35         for(int i=0;i<4;++i)
 36         {
 37             int xx=str1.x+p[i][0];
 38             int yy=str1.y+p[i][1];
 39             if(xx>=1 && xx<=n && yy>=1 && yy<=m && vis[xx][yy]==0 && (s[xx][yy]=='G' || s[xx][yy]=='.'))
 40             {
 41                 vis[xx][yy]=1;
 42                 str2.x=xx;
 43                 str2.y=yy;
 44                 r.push(str2);
 45             }
 46         }
 47     }
 48     return num;
 49 }
 50 int main()
 51 {
 52     int t;
 53     scanf("%d",&t);
 54     while(t--)
 55     {
 56         int flag=0,num=0;
 57         scanf("%d%d",&n,&m);
 58         for(int i=0;i<=n+1;++i)
 59         {
 60             for(int j=0;j<=m+1;++j)
 61                 s[i][j]='#';
 62         }
 63         for(int i=1;i<=n;++i)
 64         {
 65             //memset(s[i],0,sizeof(memset(s[i])));
 66             scanf("%s",s[i]+1);
 67         }
 68         for(int i=1;i<=n;++i)
 69         {
 70             for(int j=1;j<=m;++j)
 71             {
 72                 if(s[i][j]=='B')
 73                 {
 74                     if(s[i+1][j]=='G' || s[i][j+1]=='G' || s[i-1][j]=='G' || s[i][j-1]=='G')
 75                     {
 76                         //printf("******\n\n");
 77                         flag=1;
 78                         break;
 79                     }
 80                     if(s[i+1][j]=='.')
 81                     {
 82                         s[i+1][j]='#';
 83                     }
 84                     if(s[i][j+1]=='.')
 85                     {
 86                         s[i][j+1]='#';
 87                     }
 88                     if(s[i-1][j]=='.')
 89                     {
 90                         s[i-1][j]='#';
 91                     }
 92                     if(s[i][j-1]=='.')
 93                     {
 94                         s[i][j-1]='#';
 95                     }
 96                 }
 97                 else if(s[i][j]=='G')
 98                     num++;
 99             }
100             if(flag) break;
101         }
102         str1.x=n;
103         str1.y=m;
104         memset(vis,0,sizeof(vis));
105         vis[n][m]=1;
106         if((s[n][m]=='#' && num) || flag)
107         {
108             printf("No\n");
109             continue;
110         }
111         while(!r.empty())
112             r.pop();
113         r.push(str1);
114         int ans=bfs();
115         if(ans==num)
116             printf("Yes\n");
117         else printf("No\n");
118     }
119     return 0;
120 }

 

posted @ 2020-07-15 16:38  kongbursi  阅读(147)  评论(0编辑  收藏  举报