小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫。
- 为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。
- 小青蛙初始在(0,0)位置,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径)。
- 小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,小青蛙将无法逃离迷宫。
- 现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达到(0,m-1)位置)。
输入描述:
输入包括n+1行:
第一行为三个整数n,m(3 <= m,n <= 10),P(1 <= P <= 100) 接下来的n行:
每行m个0或者1,以空格分隔
输出描述:
如果能逃离迷宫,则输出一行体力消耗最小的路径,输出格式见样例所示;
如果不能逃离迷宫,则输出"Can not escape!"。
测试数据保证答案唯一
该方法相比于基础的迷宫问题
广度优先算法比深度优先算法更容易计算最短距离
# 读取数据
N,M,P = [int(x) for x in input().split()]
maze,path = [],[]
v, u, d = 1, 3, 0 # v-vertical;u-up;d-down
for _ in range(N):
maze.append([int(x) for x in input().split()])
# 定义转移矩阵 用于记录每个点的上一个点
state = [[None for _ in range(M)] for _ in range(N)]
state[0][0] = (0, 0, P)
start, end = (0, 0), (0, M-1)
# 迭代方式
move = [(1, 0, u), (-1, 0, d), (0, 1, v), (0, -1, v)]
# 向上 向下 向右 向左
# 添加起点
path.append((0, 0, P))
flag = True
# 深度优先算法
def bfs(i0, j0, k, p0):
# 计算下一个点
i1 = i0 + move[k][0]
j1 = j0 + move[k][1]
p1 = p0 - move[k][2]
# 判断是否可行
if not 0 <= i1 < N or not 0 <= j1 < M or p1 < 0:
return
if state[i1][j1] is not None or maze[i1][j1] <1:
return
# 更新状态
path.append((i1, j1, p1))
state[i1][j1] = (i0, j0, p0)
return
while(path and flag):
now = path.pop()
i, j, energy = now
# 尝试4种方向
for k in range(4):
bfs(i, j, k, energy)
if path and path[-1][0:2] == end:
flag = False
break
# 还原路径
if path and path[-1][0:2] == end:
x, y = end
res = '['+str(x)+','+str(y)+']'
while((x, y) != start):
x, y = state[x][y][0:2]
res = '['+str(x)+','+str(y)+']'+','+res
print(res)
else:
print("Can not escape!")