地牢逃脱-网易python(走迷宫BFS)

题目描述
给定一个 n 行 m 列的地牢,其中 ‘.’ 表示可以通行的位置,’X’ 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。
输入描述:
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 50),表示地牢的长和宽。接下来的 n 行,每行 m 个字符,描述地牢,地牢将至少包含两个 ‘.’。接下来的一行,包含两个整数 x0, y0,表示牛牛的出发位置(0 <= x0 < n, 0 <= y0 < m,左上角的坐标为 (0, 0),出发位置一定是 ‘.’)。之后的一行包含一个整数 k(0 < k <= 50)表示牛牛合法的步长数,接下来的 k 行,每行两个整数 dx, dy 表示每次可选择移动的行和列步长(-50 <= dx, dy <= 50)

输出描述:
输出一行一个数字表示最坏情况下需要多少次移动可以离开地牢,如果永远无法离开,输出 -1。以下测试用例中,牛牛可以上下左右移动,在所有可通行的位置.上,地牢出口如果被设置在右下角,牛牛想离开需要移动的次数最多,为3次。
示例1
输入

3 3



0 1
4
1 0
0 1
-1 0
0 -1

输出
3

题意:
首先题目意思表述不清,真实意思应该是:从给定起点(一定为’.’),按照给定的若干跳跃(可以跨过障碍,但不可以落在’x’上),到达任意一个’.’的最小步骤次数集合中,选择一个最大的!只要有一个’.’的点不能到达即视为无解,返回-1。

解析:
直接使用广度优先搜索(相当于树的层次遍历),通过使用队列形式,将走过的路径保存为队列,并将走过的路径所在的路径位置进行计数,用于计算最终的结果(即最远距离)。

# 走迷宫-地牢逃脱(BFS-广度优先搜索、类似于树的层次遍历)

import queue

# 定义一个Point类,用于表示点的坐标
class Point:
    x = 0
    y = 0

    def __init__(self,x,y):
        self.x = x
        self.y = y

    # 点的移动方向
    def go(self,index):
        return Point(self.x+direction[index][0],self.y+direction[index][1])

    # 所在的点是否可以移动(即既不在边界外,也不是'X'标志)
    def isOk(self):
        if self.x>=0 and self.y>=0 and self.x<n and self.y<m and pointMap[self.x][self.y]=='.':
            return True
        else:
            return False

n,m = map(int,input().split())

pointMap = [list(input()) for i in range(n)]

x0,y0 = map(int,input().split())

k = int(input())

direction = [list(map(int,input().split())) for i in range(k)]

# 初始化数组vis,存储位置是否可以通达,以及通过队列存储被第几次访问(记录最大步数)
# 其中0,表示不可通达
vis = [[0 for i in range(m)] for j in range(n)]

start = Point(x0,y0)
q = queue.Queue()
q.put(start)

# 广度优先搜索
while not q.empty():
    temp = q.get() # 弹出队头元素(remove and get)
    for i in range(0,k):
        nextPoint = temp.go(i)
        # 下一个点合法且没有走过(如果走过,则存在重复计数)
        if nextPoint.isOk() and vis[nextPoint.x][nextPoint.y]==0:
            vis[nextPoint.x][nextPoint.y] = vis[temp.x][temp.y] + 1
            q.put(nextPoint)

result = 0
route = True
for i in range(n):
    for j in range(m):
        p = Point(i,j)
        # 寻找是否存在'.'的点无法到达,如果是,则返回-1(即设置为false)
        if vis[i][j]==0 and p.isOk():
            # 由于起点初始为0,所以需要排除起点
            if i == x0 and j == y0:
                continue
            else:
                route = False
        result = max(result,vis[i][j])

if route:
    print(result)
else:
    print(-1)
阅读更多
换一批

没有更多推荐了,返回首页