博客
关于我
【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)
阅读量:820 次
发布时间: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 内核深度优化
    查看>>
    mysql 内连接、自然连接、外连接的区别
    查看>>
    mysql 写入慢优化
    查看>>
    mysql 分组统计SQL语句
    查看>>
    Mysql 分页
    查看>>
    Mysql 分页语句 Limit原理
    查看>>
    MySql 创建函数 Error Code : 1418
    查看>>
    MySQL 创建新用户及授予权限的完整流程
    查看>>
    mysql 创建表,不能包含关键字values 以及 表id自增问题
    查看>>
    mysql 删除日志文件详解
    查看>>
    mysql 判断表字段是否存在,然后修改
    查看>>
    MySQL 到底能不能放到 Docker 里跑?
    查看>>
    mysql 前缀索引 命令_11 | Mysql怎么给字符串字段加索引?
    查看>>
    mysql 协议的退出命令包及解析
    查看>>
    mysql 参数 innodb_flush_log_at_trx_commit
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    MySQL 命令和内置函数
    查看>>
    mysql 四种存储引擎
    查看>>
    MySQL 在并发场景下的问题及解决思路
    查看>>
    MySQL 基础模块的面试题总结
    查看>>