D. Solve The Maze

这篇博客探讨了如何解决一个迷宫问题,其中Vivek需要阻止坏人逃出而确保好人能够逃脱。迷宫由不同类型的单元格组成,包括空地、墙、好人和坏人。Vivek可以将空地改造成墙来阻止路径。博客介绍了如何确定是否存在一种方法,在不阻碍好人的情况下阻止所有坏人的逃脱。文章包含多个示例和解决方案,并提供了输入输出示例以帮助理解问题。

链接:https://codeforces.ml/contest/1365/problem/D

Vivek has encountered a problem. He has a maze that can be represented as an n×mn×m grid. Each of the grid cells may represent the following:

  • Empty — '.'
  • Wall — '#'
  • Good person  — 'G'
  • Bad person — 'B'

The only escape from the maze is at cell (n,m)(n,m).

A person can move to a cell only if it shares a side with their current cell and does not contain a wall. Vivek wants to block some of the empty cells by replacing them with walls in such a way, that all the good people are able to escape, while none of the bad people are able to. A cell that initially contains 'G' or 'B' cannot be blocked and can be travelled through.

Help him determine if there exists a way to replace some (zero or more) empty cells with walls to satisfy the above conditions.

It is guaranteed that the cell (n,m)(n,m) is empty. Vivek can also block this cell.

Input

The first line contains one integer tt (1≤t≤100)(1≤t≤100) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers nn, mm (1≤n,m≤50)(1≤n,m≤50) — the number of rows and columns in the maze.

Each of the next nn lines contain mm characters. They describe the layout of the maze. If a character on a line equals '.', the corresponding cell is empty. If it equals '#', the cell has a wall. 'G' corresponds to a good person and 'B' corresponds to a bad person.

Output

For each test case, print "Yes" if there exists a way to replace some empty cells with walls to satisfy the given conditions. Otherwise print "No"

You may print every letter in any case (upper or lower).

Example

input

Copy

6
1 1
.
1 2
G.
2 2
#B
G.
2 3
G.#
B#.
3 3
#B.
#..
GG.
2 2
#B
B.

output

Copy

Yes
Yes
No
No
Yes
Yes

Note

For the first and second test cases, all conditions are already satisfied.

For the third test case, there is only one empty cell (2,2)(2,2), and if it is replaced with a wall then the good person at (1,2)(1,2) will not be able to escape.

For the fourth test case, the good person at (1,1)(1,1) cannot escape.

For the fifth test case, Vivek can block the cells (2,3)(2,3) and (2,2)(2,2).

For the last test case, Vivek can block the destination cell (2,2)(2,2).

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll T,n,m,flag;
ll a[100][100],k,s;
char x[100][100];
void dfs(int i,int j)
{
    if(a[i+1][j]==0&&(x[i+1][j]=='.'||x[i+1][j]=='G')&&i+1<n)
    {
        a[i+1][j]=1;
        dfs(i+1,j);
    }
    if(a[i-1][j]==0&&(x[i-1][j]=='.'||x[i-1][j]=='G')&&i-1>=0)
    {
        a[i-1][j]=1;
        dfs(i-1,j);
    }
    if(a[i][j+1]==0&&(x[i][j+1]=='.'||x[i][j+1]=='G')&&j+1<m)
    {
        a[i][j+1]=1;
        dfs(i,j+1);
    }
    if(a[i][j-1]==0&&(x[i][j-1]=='.'||x[i][j-1]=='G')&&j-1>=0)
    {
        a[i][j-1]=1;
        dfs(i,j-1);
    }
}
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        for(int i=0;i<n;i++)
        {
            cin>>x[i];
        }
        flag=1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(x[i][j]=='B')
                {
                    if(i<n-1)
                    {
                        if(x[i+1][j]=='.')
                        {
                            x[i+1][j]='#';
                        }
                        else if(x[i+1][j]=='G')
                        {
                            flag=0;
                            break;
                        }
                    }
                    if(j<m-1)
                    {

                        if(x[i][j+1]=='.')
                        {
                            x[i][j+1]='#';
                        }
                        else if(x[i][j+1]=='G')
                        {
                            flag=0;
                            break;
                        }
                    }
                    if(j>0)
                    {

                        if(x[i][j-1]=='.')
                        {
                            x[i][j-1]='#';
                        }
                        else if(x[i][j-1]=='G')
                        {
                            flag=0;
                            break;
                        }
                    }
                    if(i>0)
                    {

                        if(x[i-1][j]=='.')
                        {
                            x[i-1][j]='#';
                        }
                        else if(x[i-1][j]=='G')
                        {
                            flag=0;
                            break;
                        }
                    }
                }
                if(flag==0)
                    break;
            }
        }
        if(x[n-1][m-1]=='B')
            flag=0;
        memset(a,0,sizeof(a));
        a[n-1][m-1]=1;
        dfs(n-1,m-1);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(x[i][j]=='G')
                {
                    if(x[n-1][m-1]=='#')
                    {
                        flag=0;
                        break;
                    }
                    if(a[i][j]==0)
                    {
                        flag=0;
                        break;
                    }
                }
            }
            if(flag==0)
                break;
        }
        if(flag)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
}

 

import numpy as np class Point: def __init__(self, x, y): self.x = x self.y = y self.f = 0 def setF(self, f): self.f = f def __eq__(self, other): return self.x == other.x and self.y == other.y ########## Begin ########## # 曼哈顿距离比较 f = g + h,h=1 def getFunctionValue(self, end_point): # 计算曼哈顿距离作为启发式函数 h h = abs(self.x - end_point.x) + abs(self.y - end_point.y) # 假设 g 值为 1(每走一步 g 增加 1) g = 1 return g + h ########## Eed ########## class State: def __init__(self, state, current_point=Point(0, 0), end_point=Point(0, 0)): self.state = state self.cP = current_point self.eP = end_point def __eq__(self, other): return self.cP == other.cP def setF(self, f): self.f = f def setCurrentPoint(self, x, y): self.cP.x = x self.cP.y = y def getCurPoint(self): return self.cP.x, self.cP.y # 确定下一步的方法 def nextStep(map, openTable, closeTable, wrongTable): subPoints = [] boarder = len(map.state) - 1 # 获取当前所在的点 x, y = map.getCurPoint() # 往左走 if y > 0 and map.state[x][y - 1] == 0: p = Point(x, y - 1) if p not in closeTable and p not in wrongTable: # 添加到可以走的list openTable.append(p) # new point # 获取F函数值 p.setF(p.getFunctionValue(map.eP)) subPoints.append(p) # 往上走 if x > 0 and map.state[x - 1][y] == 0: p = Point(x - 1, y) if p not in closeTable and p not in wrongTable: openTable.append(p) p.setF(p.getFunctionValue(map.eP)) subPoints.append(p) # 任务:完成往下走的代码逻辑 ########## Begin ########## if x < boarder and map.state[x + 1][y] == 0: p = Point(x + 1, y) if p not in closeTable and p not in wrongTable: openTable.append(p) p.setF(p.getFunctionValue(map.eP)) subPoints.append(p) ########## Eed ########## # 往右走 if y < boarder and map.state[x][y + 1] == 0: p = Point(x, y + 1) if p not in closeTable and p not in wrongTable: openTable.append(p) p.setF(p.getFunctionValue(map.eP)) subPoints.append(p) # 根据F值排序,获取F值最近的 subPoints.sort(key=compareF) if len(subPoints) < 1: # 防止走到死路无法回头情况 wrongTable.append(Point(map.cP.x, map.cP.y)) closeTable.remove(map.cP) next_point = closeTable[-1] map.cP.x, map.cP.y = next_point.x, next_point.y else: next_point = subPoints[0] map.cP.x, map.cP.y = next_point.x, next_point.y closeTable.append(next_point) openTable.remove(next_point) # 迭代走下一步 def solve(map, openTable, closeTable, wrongTable): # start the loop while not map.cP == map.eP: nextStep(map, openTable, closeTable, wrongTable) def compareF(p): return p.f # 展示最后结果 def showInfo(map, path): for i in range(len(map.state)): for j in range(len(map.state)): if Point(i, j) in path: # 正确路径用‘*’表示 print('*', end=' ') else: print(map.state[i, j], end=' ') print("\n") return if __name__ == '__main__': # openList openTable = [] # closeList closeTable = [] # 走错路返回用的 wrongTable = [] state = np.array([[0, 0, 0, 0, 0], [1, 0, 1, 0, 1], [0, 0, 0, 0, 1], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0]]) # 起点终点 start_point = Point(0, 0) end_point = Point(4, 4) # 最终路径 path = [start_point] Map = State(state, Point(0, 0), end_point) solve(Map, openTable, closeTable, wrongTable) print('Best Way:') path = path + closeTable showInfo(Map, path) print("Total steps is %d" % (len(path) - 1)) 补充以上代码,生成迷宫,使之能在Pycharm中运行。 1走迷宫过程可视化 2速度不要太快,能看清走迷宫的过程 3体现宽度优先算法过程(能找出最优解但访问到的点数最多,耗时最长)
最新发布
10-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值