题解 | #汉诺塔#

分析

假设函数 move(n, src, aux, dst) 表示把 n 个盘子从 src 移到 dstaux 为辅助杆):

  1. 基准情形(Base Case)

    • n == 1,直接输出 “src dst”(把唯一盘子从源杆移到目标杆),返回。
  2. 递推情形(Recursive Case)

    • 步骤 1move(n‑1, src, dst, aux)
      —— 把上面的 n‑1 个盘子从 src 借助 dst 移动到 aux(此时 aux 成为目标杆)。
    • 步骤 2:输出 “src dst”
      —— 把第 n 个(最底层) 大盘子从 src 直接移到 dst
    • 步骤 3move(n‑1, aux, src, dst)
      —— 把刚才挪到 aux 上的 n‑1 个盘子借助 src 移动到 dst
  3. 递归结束

    • 当所有递归调用返回,所有盘子的移动已经按最优顺序完成,输出序列即为所求。

说明

  • 输出格式的每一行都是两个字母(如 A C),正好对应一次合法的搬动。
  • 递归顺序保证大盘永远在小盘下面,从而满足题目规则。
  • 若使用 迭代/非递归 方式,可采用二进制(Gray 码)或栈模拟递归的思路,但本质仍是产生同样的 2^n‑1 步移动序列。

递归实现

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void hanoi(int n, char src, char aux, char dst) {
    if (n == 0)
        return;
    if (n == 1) {
        cout << src << " " << dst << endl;
        return;
    }
    // move n - 1 from src to aux
    hanoi(n - 1, src, dst, aux);
    // move bottom to dst
    cout << src << " " << dst << endl;
    // move n - 1 from aux to dst
    hanoi(n - 1, aux, src, dst);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    hanoi(n, 'A', 'B', 'C');
}
算法编程训练 文章被收录于专栏

各类牛客算法编程训练联赛、集训营

全部评论

相关推荐

11-09 11:15
门头沟学院 Java
1.在阿里云实习怎么做的?组里做的是什么?需求来了你是怎么上手做的?&nbsp;有什么成长,技术上学到什么?我说了个具体的例子,主要聊了消息队列解耦,还有学习内部技术论坛的帖子。2.什么情况下应该去解耦?3.聊一个技术论坛上看到的最有收获的技术,聊了RocketMQ和Kafka区别,零拷贝,存弭¦一储秣海,高可用,namespace等等4.如果你在一个新团队,你怎么选择用RMQ还是Kafka呢?我主要说看业务场景和企业基础建设。5.https和&nbsp;http区别。讲了https加密过程,数字证书。反问我那请求时候的url会不会加密呢?6.去哪申请数字证书?了解过有证书颁发机构,具体不知道。7.如果私钥泄漏了该怎么办?我先回答换私钥,他问还有呢?私钥泄漏了中间人就可以拿到数字证书了。然后我回答去废弃老的数字证书。8.tcp和udp区别?聊了udp不可靠,聊了qq之前的实现(用&nbsp;udp改的,所以QQ聊天会乱序)序)。他问我那想要udp快捷但是不乱序怎么办?能从应用层改吗?我说感觉还是得从传输层改&nbsp;udp协议。9.synchronized和reentrantlock区别10.hashmap底层11.String怎么保证不可变的?答了字符串常量池(感觉他想让我说&nbsp;String底层用的&nbsp;final)12.项目里乐观锁防超卖咋做的?13.gc日志看了什么?14.项目用的哪个垃圾回收器?15.sql注入是什么?怎么防范?我说用安全包防范,他问我包里面那些具体实现。只回答了一个字符串过滤,16.jwt是怎么实现的?聊了无状态,签名算法。他问我签名算法有哪些?保证了什么性质?算法:两个有序list合并
查看17道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务