博客
关于我
【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)
阅读量:813 次
发布时间:2023-04-17

本文共 2380 字,大约阅读时间需要 7 分钟。

为了解决这个问题,我们需要模拟汉诺塔的移动过程,根据给定的操作优先级,计算按照特定策略移动盘子所需的最小步骤数。我们将使用模拟器的方法来逐步模拟每一步操作,确保每次移动都符合规则。

方法思路

  • 初始化:将盘子从柱子A开始,逐层放置在A柱子上。
  • 优先级处理:按照给定的优先级顺序,依次检查每个操作是否可以执行。
  • 合法性检查:每次操作必须确保盘子的移动是合法的,盘子不能放在比它大的盘子上面,且不能移动上一次移动的盘子。
  • 更新状态:每次执行合法的操作后,更新各柱子的盘子堆、最上面盘子的位置以及记录上一次移动的盘子和柱子。
  • 循环直到完成:继续处理直到所有盘子都移动到目标柱子B或C。
  • 解决代码

    n = int(input())priority_str = input().split()A_pile = list(range(n, 0, -1))B_pile = []C_pile = []top = [n, 0, 0]pos = [0] * (n + 1)last_moved_disk = -1last_move_from = Nonelast_move_to = Nonecount = 0while True:    if top[0] == 0:        break    found = False    for op in priority_str:        src, dst = op[0], op[1]        # 检查源柱子是否有盘子        if src == 'A':            src_pile = A_pile        elif src == 'B':            src_pile = B_pile        else:            src_pile = C_pile        if not src_pile:            continue        x = src_pile[0]        # 检查是否是上一次移动的盘子        if last_moved_disk != -1 and x == last_moved_disk:            continue        # 检查目标柱子是否可以放下x        if dst == 'A':            dst_pile = A_pile        elif dst == 'B':            dst_pile = B_pile        else:            dst_pile = C_pile        if not dst_pile:            # 目标为空,可以放下x            pass        else:            y = dst_pile[0]            if y > x:                pass            else:                continue        # 执行该操作        # 移除x        if src == 'A':            A_pile.remove(x)        elif src == 'B':            B_pile.remove(x)        else:            C_pile.remove(x)        # 插入x到目标柱子        if dst == 'A':            A_pile.insert(0, x)        elif dst == 'B':            B_pile.insert(0, x)        else:            C_pile.insert(0, x)        # 更新top数组        if src == 'A':            top[0] = A_pile[0]        elif src == 'B':            top[1] = B_pile[0]        else:            top[2] = C_pile[0]        top[dst] = x        # 更新pos数组        if dst == 'B':            pos[x] = 1        elif dst == 'C':            pos[x] = 2        else:            pos[x] = 0        # 记录上一次移动的盘子和柱子        last_moved_disk = x        last_move_from = src        last_move_to = dst        count += 1        found = True        break    if not found:        continueprint(count)

    代码解释

  • 读取输入:读取盘子数量n和优先级字符串。
  • 初始化盘子堆:将盘子从下到上依次放在A柱子上。
  • 模拟器循环:直到A柱子为空为止,依次处理每个操作。
  • 优先级处理:从高优先级到低优先级检查每个操作是否可以执行。
  • 合法性检查:确保移动的盘子不是上一次移动的盘子,目标柱子可以放下盘子。
  • 更新状态:执行操作后,更新盘子堆、最上面盘子的位置和记录上一次移动的盘子。
  • 输出结果:当所有盘子都移动到目标柱子时,输出移动步骤数。
  • 转载地址:http://rmgfk.baihongyu.com/

    你可能感兴趣的文章
    mysql-connector-java各种版本下载地址
    查看>>
    mysql-EXPLAIN
    查看>>
    MySQL-Explain的详解
    查看>>
    mysql-group_concat
    查看>>
    MySQL-redo日志
    查看>>
    MySQL-【1】配置
    查看>>
    MySQL-【4】基本操作
    查看>>
    Mysql-丢失更新
    查看>>
    Mysql-事务阻塞
    查看>>
    Mysql-存储引擎
    查看>>
    mysql-开启慢查询&所有操作记录日志
    查看>>
    MySQL-数据目录
    查看>>
    MySQL-数据页的结构
    查看>>
    MySQL-架构篇
    查看>>
    MySQL-索引的分类(聚簇索引、二级索引、联合索引)
    查看>>
    Mysql-触发器及创建触发器失败原因
    查看>>
    MySQL-连接
    查看>>
    mysql-递归查询(二)
    查看>>
    MySQL5.1安装
    查看>>
    mysql5.5和5.6版本间的坑
    查看>>