题目链接:https://blog.csdn.net/flushhip/article/details/78267949#comments
参考:https://blog.csdn.net/ming991301630/article/details/82903059
import collections
sx,sy = 0,0
bx,by = 0,0
cnt = 0
## 得到人的位置左边sx,sy和箱子的位置坐标bx,xy
for i in range(n):
for j,v in enumerate(mp[i]):
if v == 'S':
sx,sy = i,j
cnt += 1
break
elif v == '0':
bx,by = i,j
cnt += 1
break
if cnt == 2:
break
visited = {} #用来记录该状态是否出现过,同时记录达到该状态时一共走了多少步。出现过说明已经走过了,没有必要重复走
queue = collections.deque() #bfs需要用双端队列实现
def bfs(mp,sx,sy,bx,by):
visited[(sx,sy,bx,by)] = 0
queue.append([sx,sy,bx,by])
dx = [1,-1,0,0]
dy = [0,0,1,-1]
cnt = -1
while queue:
sx,sy,bx,by = queue.popleft()
for k in range(4):
tx,ty = sx+dx[k],sy+dy[k]
if 0 <= tx < n and 0 <= ty < m and mp[tx][ty] != '#' and (tx,ty,bx,by) not in visited:
if (tx,ty) == (bx,by): #判断人是否和当前箱子位置重合,如果重合,则进行推箱子
ax,ay = bx+dx[k],by+dy[k]
if 0 <= ax < n and 0 <= ay < m and mp[ax][ay] == 'E': #判断推了箱子之后,箱子的位置是否合理且到达终点
return visited[(sx,sy,bx,by)]+1
visited[(tx,ty,ax,ay)] = visited[(sx,sy,bx,by)]+1 #当前状态的步数=前一状态+1
queue.append([tx,ty,ax,ay])
else: # 人和箱子的位置没有重合,则人继续走,箱子不动
visited[(tx,ty,bx,by)] = visited[(sx,sy,bx,by)]+1
queue.append([tx,ty,bx,by])
return -1
print(bfs(mp,sx,sy,bx,by))