牛客 地下迷宫(python)

小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值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!")


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁lingling哇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值