【DFS题型九/双向DFS】王子救公主

题目描述:

一天,蒜头君梦见自己当上了王子,但是不幸的是,自己的公主被可恶的巫婆抓走了。于是蒜头君动用全国的力量得知,自己的公主被巫婆抓进一个迷宫里面。由于全国只有蒜头君自己可以翻越迷宫外的城墙,蒜头君便自己一人走上的拯救自己公主的路途。
碰巧的是巫婆出去了,迷宫也不大,蒜头君可以直接和公主对话,于是两个人便开始相互靠近。每一步移动只能朝着上下左右四个方向走一格,不能走进墙所在的位置。蒜头君救公主心切,一次必须沿着一个方向走两步(允许跨越迷宫中的墙);公主柔弱,一次只能走一步。问在这个迷宫中,蒜头君是否可以救出公主(蒜头君和公主相遇后,就能背着公主逃出迷宫了)。
输入格式
第一行输入两个整数 n(1≤n≤100), m(1≤m≤100) 表示迷宫的行和列。
然后有一个 n×m 的地图,地图由’.’、’#’、‘w’、‘g’这四个部分组成。’.‘表示可以通行的路,’#'表示迷宫的墙,'w’表示王子开始所在的位置,'g’表示公主开始所在的位置。
输出格式
输出王子是不可以救出自己的公主,如果能救出则输出"yes",否则输出"no"。
样例输入
1 8
w….#.g
样例输出
yes

 思路:

标记vis建立为三维,一维存王子(d=0),一维存公主(d=1),(回溯时不将vis清零)若存在重合点就说明可以相遇。

好处可以两个通用一个dfs函数,当d=0时,步长为2-d也就是2,为王子;当d=1时,步长为2-d也就是1,为公主。

n,m=map(int,input().split())
maze=[]
for i in range(n):
    list1=list(input())
    maze.append(list1)
vis=[[[0]*2 for i in range(m)] for j in range(n)]
#print(vis)
def dfs(x,y,d):#目的就是改变vis的值,所以没有return也可以
    vis[x][y][d] = 1#
    for dx,dy in [(2-d,0),(-2+d,0),(0,2-d),(0,-2+d)]:
        nx=dx+x
        ny=dy+y
        if 0<=nx<n and 0<=ny<m and vis[nx][ny][d]!=1 and maze[nx][ny]!='#':
            #vis[x][y][d] = 1  放这里最后一步的vis更新
            dfs(nx,ny,d)

for i in range(n):
    for j in range(m):
        if maze[i][j]=='w':
            x=i
            y=j
#print(x,y)
dfs(x,y,0)
#print(vis)

for i in range(n):
    for j in range(m):
        if maze[i][j]=='g':
            x=i
            y=j
#print(x,y)
dfs(x,y,1)
#print(vis)

ans=False
for i in range(n):
    for j in range(m):
        if vis[i][j][0]==1 and vis[i][j][1]==1:
            ans=True
if ans:
    print('yes')
else:
    print('no')

n,m=map(int,input().split())
maze=[]
for i in range(n):
    list1=list(input())
    maze.append(list1)
vis=[[[0]*2 for i in range(m)] for j in range(n)]
#print(vis)
def dfs(x,y,d):
    if 0 > x or x>= n or 0 > y or y>= m or vis[x][y][d] == 1 or maze[x][y] == '#':
        return
    vis[x][y][d] = 1#
    dfs(x+(2-d),y,d)
    dfs(x - (2 - d), y, d)
    dfs(x , y+ (2 - d), d)
    dfs(x , y- (2 - d), d)

for i in range(n):
    for j in range(m):
        if maze[i][j]=='w':
            x=i
            y=j
#print(x,y)
dfs(x,y,0)
#print(vis)

for i in range(n):
    for j in range(m):
        if maze[i][j]=='g':
            x=i
            y=j
#print(x,y)
dfs(x,y,1)
#print(vis)

ans=False
for i in range(n):
    for j in range(m):
        if vis[i][j][0]==1 and vis[i][j][1]==1:
            ans=True
if ans:
    print('yes')
else:
    print('no')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值