题目描述
给定一个 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)