汉罗塔(河内之塔)问题

游戏规则:

有A,B,C三根针,将A针上N个从小到大叠放的盘子移动到C针,一次只能移动一个,不重复移动,小盘子必须在大盘子上面。

问题:

总的移动次数是多少?

分析:

(1)n == 1

             第1次  1号盘  A—->C       sum = 1 次

       (2)  n == 2

             第1次  1号盘  A—->B

             第2次  2号盘  A—->C

             第3次  1号盘  B—->C        sum = 3 次

  (3)n == 3

        第1次  1号盘  A—->C

        第2次  2号盘  A—->B

        第3次  1号盘  C—->B

        第4次  3号盘  A—->C

        第5次  1号盘  B—->A

        第6次  2号盘  B—->C

        第7次  1号盘  A—->C        sum = 7 次

 

不难发现规律:1个圆盘的次数 2的1次方减1

       2个圆盘的次数 2的2次方减1

                         3个圆盘的次数 2的3次方减1

                         。  。   。    。   。 

                         n个圆盘的次数 2的n次方减1

 故:移动次数为:2^n – 1

而对于汉罗塔的具体移动方法,我从很久之前就开始疑惑,对于盘子数量为 1 ,为 2,为 3 这个我们都好说,也好模拟计算,至于移动的次数也很容易计算出来,从而推导出来 n 个盘子的移动次数,但是你有没有和我之前一样的困惑呢?具体如何移动的呢?其实真的不用去细细的琢磨,我们知道无非就是三个盘子之间的移动呗,但是如果从从整体的盘子移动的去向来考虑,我们要的结果就是将 A 针上的所有盘子转移到 C 盘子上,而且在移动的过程中有一个限制条件就是小盘子一定在大盘的上面,我们由简到繁来分析:

如果 A 针上有一个盘子,我们就直接将该盘子移动到 C 盘子上,就 OK 了!

如果 A 针上有 n 个盘子,那么我们就要借助 C 针将 n-1 个盘子移动到 B 针上(这时 B 针是过度针),再将第 n 个盘子移动到 C 针上,这样完了之后,B 针上有 n-1个盘子,C 针上有 1 个盘子,而 A 针上没有盘子,但是 B 针上的 n-1 个盘子都比 C 针上的那一个盘子小,于是这时,我们需要将B 针上的转移到 C 针,这时 A 针就是过度针了~

代码实现:

#include <iostream>
#include<stdio.h>
#include<math.h>
using namespace std;

void Move(int n,char a,char b,char c)
{
    if(n==1)///如果一个盘子就直接转移
        printf("Move sheet %d form %c to %c\n",n,a,c);
    else///如果是 n 个盘子
    {
        Move(n-1,a,c,b);///我们首先要将 1~n-1 个盘子以 C 针作过度转移到 B 针上
        printf("Move sheet %d form %c to %c\n",n,a,b);
        Move(n-1,b,a,c);///我们再将 B 针上的 1~n-1 个盘子以 A 针作过度转移到 C 针上
    }
}

int main()
{
   int n;
   printf("请输入盘数:\n");
   scanf("%d",&n);
   Move(n,'A','B','C');///将 n 个盘子以 B 针作过度转移到 C 针上
    return 0;
}
    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/lz161530245/article/details/79341284
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞