题目
给定一个大小为N*M的迷宫,由通道(’.’)和墙壁(’#’)组成,其中通道S表示起点,通道G表示终点,每一步移动可以达到上下左右中不是墙壁的位置。试求出起点到终点的最小步数。(本题假定迷宫是有解的)
解题思路
是BFS和队列的结合应用
结合代码看,更容易理解
- 从起点开始,先将其加入队列,设置距离为0
- 从队列首端取出位置,将从这个位置能够到达的位置加入队列,并且让这些位置的距离为上一个位置的距离加上1
- 循环2直到从队列首端取出的是终点,这说明我们已经找到了路径
搜索可移动到的位置所使用的判断条件中不仅仅是不碰墙壁、不超过边界,还有一个就是没有到达过,因为如果已经到达了这个位置,这说明已经有更短的路径到达这个位置,这次到达这个位置的路径是更差的,不可能得到更好的最终解。
代码
输入demo
10
10
# S # # # # # # . #
. . . . . . # . . #
. # . # # . # # . #
. # . . . . . . . .
# # . # # . # # # #
. . . . # . . . . #
. # # # # # # # . #
. . . . # . . . . .
. # # # # . # # # .
. . . . # . . . G #
输入
22
import sys
def bfs(G,dis,sx,sy,tx,ty,N,M):
quene=[(sx,sy)]
dis[sx][sy]=0
dx=[1,0,-1,0]
dy=[0,1,0,-1]
while quene:
idx, idy = quene[0]
del quene[0]
if idx==tx and idy==ty:
return
for i,j in zip(dx,dy):
ndx = idx+i
ndy = idy+j
if ndx>=0 and ndx< N and ndy>=0 and ndy<M and G[ndx][ndy]!="#" and dis[ndx][ndy] == sys.maxsize:
dis[ndx][ndy]=dis[idx][idy]+1
quene.append((ndx,ndy))
if __name__=="__main__":
N = int(sys.stdin.readline().strip())
M = int(sys.stdin.readline().strip())
G = [] # 这是图
dis = [[sys.maxsize]*M for _ in range(N)]
sx,sy,tx,ty=-1,-1,-1,-1
for i in range(N):
tmp = sys.stdin.readline().strip().split()
if "S" in tmp:
sx=i
sy=tmp.index("S")
if "G" in tmp:
tx=i
ty=tmp.index("G")
G.append(tmp)
bfs(G, dis, sx, sy, tx, ty, N, M)
print(dis[tx][ty])