题意:
给你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("****** "); 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 "); 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 "); 117 else printf("No "); 118 } 119 return 0; 120 }