汉诺塔问题探讨

18 篇文章 0 订阅
6 篇文章 0 订阅

汉诺塔问题探讨

原题目

​ 有三根柱子,每根柱子上一开始都是空的。我们把这三个柱子编号为1, 2, 3,现在,第一根柱子上有 N 个盘子按照尺寸从小到大排列,我们的目的是把这些盘子按顺序从第一根柱子转移到第三根上。在移动过程中有要求,即每个柱子上要想往上叠加盘子,只能叠加比它尺寸小的盘子。那么我们该怎么挪?

Link 提交评测区(codevs)

思路

​ 我们先想这样一个思路,就是我们先定义一个函数kansu(x,y,z),这个函数的功能是把 x 柱子上的y个盘子按照顺序移动到 z 柱子上。在想的过程中,一定不要考虑要怎么移动,只要知道我们要移动就好了。这样,调用一遍kansu(A,N1,B),现在 B 柱子上就有依次叠好的N1个盘子了, A 上就只剩下最大的那一个,C上一个也没有。现在我们分析一下, A 上只有一个最大的,也就是说可以在A上放置任意一个盘子。那么,把 A 上剩下的那个最大的移动到C上,那么 C 上的那个就是最大的了。现在,A是空的, B 上有N1个, C 上有一个最大的。

​ 这里大家注意一下,一开始A柱子上有 N 个盘子,B柱子和 C 柱子上都没有盘子,而现在A上没有, B N1个, C 上一个最大的。正因为C上有一个最大的,所以上面可以放任意一个盘子,也就等价于空的。这样,我们就把我们要解决的移动 N 个盘子的问题简化成了移动N1个盘子的问题(只是位置不同),而这正是利用了递归的思想。

​ 现在我们完成了把一个最大的挪到 C 上的任务了,那么我们最终的任务就明了了,就是把每次的最大的挪到C柱子上,这样最大的越积越多,积到 N <script type="math/tex" id="MathJax-Element-33">N</script>个我们就得到结果了。

伪代码

S1:利用Kansu(A, N - 1, B)将A上的N - 1个盘子按照顺序移动到B柱子上
S2:利用Move(A, C)将A柱子上剩下的一个最大的盘子移动到C柱子上
S3:利用Kansu(B, N - 2, A)将B上的N - 2个盘子按照顺序移动到B柱子上
......
最后在一个一个Move的过程中,C上就按照从大到小的顺序垒好了N个盘子。

C++代码

#include <cmath>
#include <iostream>

void Hanoi(const int n, const int A, const int B, const int C)
{

    if (n > 0)
    {
        Hanoi(n - 1, A, C, B);
        std::cout << n << " from " << char (64 + t.x)  << " to " << char (64 + t.y) << '\n';
        Hanoi(n - 1, C, A, B);
    }
}


int main(int argc, char ** argv)
{
    int n;
    std::cin >> n;
    std::cout << std::pow(2, n) - 1 << std::endl;
    // 2^n - 1 表示步数总数
    Hanoi(n, 1, 3, 2);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值