蓝桥杯跳蚱蜢(bfs)

1. 问题描述:

如图所示: 有9只盘子,排成1个圆圈。其中8只盘子内装着8只蚱蜢,有一个是空盘。

蓝桥杯跳蚱蜢(bfs)

我们把这些蚱蜢顺时针编号为 1~8。每只蚱蜢都可以跳到相邻的空盘中,也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。 请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,并且保持空盘的位置不变(也就是1-8换位,2-7换位,...),至少要经过多少次跳跃? 
输出
输出一个整数表示答案 

来源:http://oj.ecustacm.cn/problem.php?id=1318

2. 思路分析:

分析题目可以知道我们已知一个初始的盘面状态,需要求解到达目标盘面状态的最少步数,根据这个原状态到目标状态的最少步数的特点可知可以使用bfs(宽度优先搜索解决),bfs可以求解出到达目标状态的最少步数,可以规定原状态为"012345678",目标状态为"087654321",将状态设置为str字符串类型这样可以直接比较原状态与目标状态是否相等。当前状态可以交换从当前0的位置算起的左右两边的第一个元素与第二个元素的位置,可以通过下图来理解具体的过程

蓝桥杯跳蚱蜢(bfs)

3. 代码如下:

import collections


def insertQueue(queue: collections.deque, dir: int, poll: tuple, vis: set):
    pos = poll[1]  # 0元素的位置
    status = poll[0]
    # 因为题目中的状态是滚动的所以需要通过对9取余实现滚动
    insertPos = (pos + dir + 9) % 9
    # 将字符串转为列表才可以交换元素, 然后再通过join方法将列表中的元素转为字符串
    t = list(status)
    t[pos], t[insertPos] = t[insertPos], t[pos]
    addStatus = "".join(t)
    if addStatus not in vis:
        vis.add(addStatus)
        queue.append((addStatus, insertPos, poll[2] + 1))


if __name__ == '__main__':
    # 因为求解的是最少的步数, 所以可以使用广度优先搜索解决
    queue = collections.deque()
    # 第一个参数为初始状态, 第二个参数是空盘子的位置, 第三个参数为到达当前状态的步数
    queue.append(("012345678", 0, 0))
    # 标记列表
    vis = set()
    vis.add("012345678")
    while queue:
        poll = queue.popleft()
        # 到达了目标状态那么输出最少步数即可
        if poll[0] == "087654321":
            print(poll[2])
            break
        # 可以向左边或者是右边跳一个或者是两个位置
        insertQueue(queue, -2, poll, vis)
        insertQueue(queue, -1, poll, vis)
        insertQueue(queue, 1, poll, vis)
        insertQueue(queue, 2, poll, vis)

 

上一篇:Linux c++(socket网络通信 & poll)


下一篇:找树左下角的值(递归,迭代)JAVA!