算法-汉诺塔

问题描述

  问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

 

  也就是要遵守两点要求:1、每次只能移动1个盘 。2、大盘不能放在小盘下面。

分析问题

  假设盘子数为n。X、Y、Z是代表三根柱子。

  Ⅰ、n=1时:1、X --> Z      (移动1次)

 

  Ⅱ、n=2时: 1、X --> Y

        2、X --> Z

        3、Y --> Z      (移动1+1+1=3次)

 

  Ⅲ、n=3时: 1、 X --> Z

        2、X --> Y

        3、Z --> Y

        4、X --> Z

        5、Y --> X

        6、 Y --> Z

        7、X --> Z      (移动3+1+3=7次)

 

  Ⅳ、n=4时: 1、X --> Y

        2、X --> Z
        3、Y --> Z
        4、X --> Y
        5、Z --> X
        6、Z --> Y
        7、X --> Y
        8、X --> Z
        9、Y --> Z
        10、Y --> X
        11、Z --> X
        12、Y --> Z
        13、X --> Y
        14、X --> Z
        15、Y --> Z  (移动7+1+7=15次)

 

  N:n=n时:(n-1)个盘子的移动次数 + 1 + (n-1)个盘子的移动次数 。

 

  我们也可发现汉诺塔的规律:1个圆盘的次数21-1、 2个圆盘的次数22-1、 3个圆盘的次数23-1、 n个圆盘的次数2n-1。

  而且可以发现的是移动中有一半的步骤是将盘子从 X 柱移往 Y 柱,也就是随着盘子的增加,所需的步数是指数上升的。

  最后在人工移动时我们可以得出一个套路:先将 X 柱上的除最后一块盘子借助 Z 先移动到 Y 上,再将最后一块移到 Z 上,之后将 Y 柱视为 X ,重复上述,即可机械的完成移动。

  以上总结为:

      ▼ 第一步:先把 X 上的前(n-1)个盘子放到 Y 上(占步数的一半)

      ▼ 第二步:再把 X 上最下面的盘子放在 Z 上

      ▼ 第三步:最后把 Y 上的(n-1)个盘子放在 Z 上

算法实现

int i=1;
void h(int n,char x,char y,char z){
     if(n==1)
         printf("%d、%c --> %c\n",i++,x,z);
     else{
         h(n-1,x,z,y);
         printf("%d、%c --> %c\n",i++,x,z);
         h(n-1,y,x,z);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值