题目链接:https://www.lanqiao.cn/problems/602/learning/
思路:
1.基本算法:最短路径迷宫题采用BFS(广搜)算法
2.迷宫图的储存方法:使用二维列表逐行逐列储存地图mp
3.走迷宫应注意:
1)设置标记已走过的平行地图vis,设置走迷宫jued()函数,边界判断,用if来走迷宫;
2)储存路径的数据结构是重点,此处采用队列deque。为实现BFS需要一个空队列deque(run)来储存BFS过程:探索结点A时,判断一遍结点A的四个neighbor(相邻四点),储存能走的下一个结点入队run,随后pop将结点A弹出队列,如此往复就是BFS的过程;
4.字典序小技巧:每个结点的探图方向用‘D,L,R,U’的字典序顺序,这样BFS搜出来的第一条路径就是字典序最小的最短路径了
5.最短路径储存方法:前驱结点记录法:探图时用字典同时记录每个点的前驱结点
6.通过路径遍历四个方向来生成脚印
代码:
import collections
s='''01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000'''
mp=[[int(i) for i in j ]for j in s.split('\n')]
vis=[[False for i in j ]for j in s.split('\n')]#标记访问
run=collections.deque() #BFS用队列
path=[] #路径
dire=[(0,1),(-1,0),(1,0),(0,-1)] #字典序D,L,R,U
def jued(x,y): #走迷宫函数
if mp[y][x]==0 and vis[y][x]==False:
return True
dic={} #用字典记录前驱结点
def bfs(): #广搜
run.append((0,0))
while len(run)!=0:
temp=0
x=run[0][0]
y=run[0][1]
vis[0][0]=True
for i in range(4):
newx = x+dire[i][0]
newy = y+dire[i][1]
if 0<=newx<=49 and 0<=newy<=29:
if jued(newx,newy)==True:
vis[newy][newx]=True
run.append((newx,newy))
dic[(newx,newy)]=(x,y)
if newx==49 and newy==29 :return 0
run.popleft()
bfs()
def find_path(x,y):#递归串联出最短路径
path.append((x,y))
if x==y==0:
return path
else:
return find_path(dic[(x,y)][0],dic[(x,y)][1])
find_path(49,29)
path=path[::-1] #倒叙路径
step=collections.deque() #脚印
for i in range(1,len(path)):#生成脚印
for j in range(4):
if path[i][0]==path[i-1][0]+dire[j][0] and path[i][1]==path[i-1][1]+dire[j][1]:
if j==0:step.append('D')
elif j==1:step.append('L')
elif j==2:step.append('R')
elif j==3:step.append('U')
break
print(''.join(step))#输出格式
#DFS输出一条路径(并非最短)方法:
'''import sys
sys.setrecursionlimit(2000)
s='......'
mp=[[int(i) for i in j] for j in s.split('\n')]
vis=[[False for i in j]for j in s.split('\n')]
di=[[-1,0],[0,-1],[1,0],[0,1]] #向左、上、右、下
path=[]
print(mp[29][49])
def dest(x,y):
if x==49 and y==29:
#True已到终点
return True
else:return False
def check(x,y):
if x in range(0,50) and y in range(0,30) and vis[y][x]==False and mp[y][x]==0 :#条件检查
return True
else : return False
def dfs(x,y):
if dest(x,y):
return True #走到终点
vis[y][x]=True
for i in range(4):
newx=x+di[i][0]
newy=y+di[i][1]
if check(newx, newy):
if i==0 :
path.append(('L',newx,newy))
return dfs(newx,newy)
if i==1 :
path.append(('U',newx,newy))
return dfs(newx,newy)
if i==2 :
path.append(('R',newx,newy))
return dfs(newx,newy)
if i==3 :
path.append(('D',newx,newy))
return dfs(newx,newy)
else:continue
path.pop() #回溯
vis[path[-1][2]][path[-1][1]]=False
return dfs(path[-1][1],path[-1][2])
dfs(0,0)
result=[]
for i in range(len(path)):
result.append(path[i][0])
print(''.join(result)) '''
总结:
BFS算法是最短路径问题最基础的方法。此类搜索题书写的代码量较多,采用的数据结构较多,如这题列表、元组、字典都灵活运用到了,但思路明确,算法不算复杂。