试题 算法提高 学霸的迷宫
问题描述
学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗。但学霸为了不要别人打扰,住在一个城堡里,城堡外面是一个二维的格子迷宫,要进城堡必须得先通过迷宫。因为班长还有妹子要陪,磨刀不误砍柴功,他为了节约时间,从线人那里搞到了迷宫的地图,准备提前计算最短的路线。可是他现在正向妹子解释这件事情,于是就委托你帮他找一条最短的路线。
输入格式
第一行两个整数n, m,为迷宫的长宽。
接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。
输出格式
第一行一个数为需要的最少步数K。
第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个。
样例输入
Input Sample 1:
3 3
001
100
110
Input Sample 2:
3 3
000
000
000
样例输出
Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR
思路:
从题意中可以看出此题是迷宫题只不过要算出如何走的位置和最短路相同时选择在此表示方法下字典序最小的一个。
我们可以知道迷宫题是个经典的bfs广域思想题,他的思想就是把开头队列存到队列中,然在用一个列表存储我走过的值,并记录走的对应轨迹。
我们第一步先建立一个函数bfs,然后在里面建存队列的列表。
我用的是d 然后在存一个开头我们知道起点是(1,1),但我从(0,0)开始的个人习惯把。我们在用一个字典键来存走过的路,值来存对应的轨迹。然后我们需要按顺序的从DLRU开始走一步。因为题目说了最短路相同时选择在此表示方法下字典序最小的一个,然后我们把走到下步的值用x1,y1存储起来, 然后我们就开始判断条件,我们首先不可以走走过的路,下面就是当p[x1,y1]p字典有这个键时我们就不管。
try:
p[x1,y1]
except:
当没有时我们就判断x1和y1是否超出界限"-1<x1<n and -1<y1<m " 然后在判断是否是可以走的路mp[x1][y1]==“0”。
当上面条件都满足时我们就把对应点放入队列中然后存储到该点的轨迹,上个点的轨迹加现在是从那边过来的反向就是本点的轨迹p[x1,y1]=p[x,y]+s[i]。当该点到终点时我们就算出终点走的轨迹。
程序:
n,m=map(int,input().split())
mp=[list(input()) for i in range(n)] #存入图
s="DLRU"
f=[[1,0],[0,-1],[0,1],[-1,0]] #各个方向标记
def bfs():
p={} #存储轨迹及 位置
d=[[0,0]] #队列存储
p[0,0]="" #存储第一个点的位置及 轨迹
while d!=[]:
x,y=d.pop(0) #取出队列的第一个点
for i in range(4):
x1=f[i][0]+x #下个点的位置
y1=f[i][1]+y
try:
p[x1,y1] #判断是否有当前这个点
except:
if -1<x1<n and -1<y1<m and mp[x1][y1]=="0" : #判断是否超界限是否路可以走
d.append([x1,y1]) #存入列表中
p[x1,y1]=p[x,y]+s[i] #记录该点的轨迹
if x1==n-1 and m-1==y1: #是否到达终点
return p[x1,y1]
c=bfs()
print(len(c))
print(c)
禁止转载。仅用于自己学习。对程序错误不负责。