洛谷p1379题八数码难题

八数码难题 - 洛谷

from collections import deque

def swap(state, i, j):
    # 将状态字符串转换为列表,以便交换元素。
    state_list = list(state)
    # 交换位置i和j处的元素。
    state_list[i], state_list[j] = state_list[j], state_list[i]
    # 将列表转换回字符串,并返回新的状态。
    return ''.join(state_list)

def bfs(initial_state, target_state):
    # 创建一个双端队列,用于存储状态及其对应的步数。
    queue = deque([(initial_state, 0)])
    # 用集合来跟踪已访问的状态,以避免重复访问。
    visited = set()

    while queue:
        # 从队列左侧弹出最左边的状态及其对应的步数。
        state, steps = queue.popleft()
        # 如果状态与目标状态匹配,则返回到达目标状态所需的步数。
        if state == target_state:
            return steps

        # 如果当前状态已访问过,则跳过它。
        if state in visited:
            continue

        # 标记当前状态为已访问。
        visited.add(state)
        # 找到当前状态中空格(用'0'表示)的索引。
        empty_index = state.index('0')

        # 计算空格('0')可能的移动位置(考虑3x3拼图网格)。
        moves = [empty_index - 1, empty_index + 1, empty_index - 3, empty_index + 3]
        for move in moves:
            # 检查移动是否在拼图网格(9个单元格)的范围内。
            if 0 <= move < 9 \
                    and (move // 3 == empty_index // 3 or move % 3 == empty_index % 3):
                # 通过交换空格与相邻单元格的位置来执行移动。
                new_state = swap(state, empty_index, move)
                # 将新状态及增加的步数计数添加到队列中。
                queue.append((new_state, steps + 1))

    # 如果无法从初始状态到达目标状态,则返回-1。
    return -1

if __name__ == "__main__":
    # 从用户输入中读取拼图的初始状态。
    initial_state = input().strip()
    # 设置目标状态为常量(3x3拼图的目标状态:123804765)。
    target_state = "123804765"
    # 使用广度优先搜索算法找到到达目标状态所需的最小步数。
    result = bfs(initial_state, target_state)
    # 将结果(步数)打印到控制台。
    print(result)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值