题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
如下图所示: 有 9 只盘子,排成 1 个圆圈。 其中 88 只盘子内装着 8 只蚱蜢,有一个是空盘。 我们把这些蚱蜢顺时针编号为 1 ~ 8。
每只蚱蜢都可以跳到相邻的空盘中, 也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列, 并且保持空盘的位置不变(也就是 1-8换位,2-7换位,...),至少要经过多少次跳跃?
这道题可以当成八数码类型的题来看,把整个圆盘拆解就是“012345678”,要变换成“087654321”,典型的八数码问题。
使用空圆盘来跳,一共有四种跳法:往前跳1,跳2和往后跳1,跳2,只要把每次跳的位置与圆盘交换位置,再比较是否到达终点便可求解这道题
代码实现
import collections
def bfs():
q = collections.deque()
dist = {} #使用字典存储步数
dist[s1] = 0
dire = [-2,-1,1,2]
q.append(s1)
while q:
now = list(q.popleft()) #将pop出来的字符串逐个加入列表,方便操作
if "".join(now) == s2:
return dist["".join(now)] #如果达到要求,返回次数
point = now.index("0") #找到移动“0”的索引
distance = dist["".join(now)] #记录当前步数
for i in dire:
new_now = now.copy()
num_index = (point + i + 9) % 9 #需要移动数的位置
new_now[point],new_now[num_index] = new_now[num_index],new_now[point] #交换
if "".join(new_now) not in dist.keys(): #如果没记录过便加入
dist.setdefault("".join(new_now),distance+1)
q.append("".join(new_now))
s1 = "012345678"
s2 = "087654321"
print(bfs())