汉诺塔游戏

1.问题:

有三根相邻的柱子,标号为A,B,C。A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘。现在把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方。为了方便说明,这里取n=3。

2.如图

根据题目,目的是把A上的盘子按照一定规则移动到B盘上,C柱只是一个辅助。在这里我们统一规定:资源地(A柱)、目的地(B柱)、C(辅助的柱子)。

3.解题思想:

(1)我们可以这样思考:

  1. 要把123转移到B(目的地)上,
  2. 就首先把12转移到C(辅助的柱子)上,
  3. 然后把3转移到B(目的地)柱上,

那现在的结果如图:

(2)接下来这样思考:

  1. 要把12转移到B柱上,
  2. 就先把1转移到A柱上,
  3. 再把2转移到B柱上

结果如图:

(3)最后把1直接转移到B柱上,这里就不画图了。

4)总结前面的三步:

  1. 我们发现B柱永远都是作为“目的地”;
  2. A柱与C柱作用互换在(1)中A柱作为“资源地”,C柱作为“辅助的柱子”;在(2)中A柱作为“辅助柱子”,C柱子作为“资源地”;在(3)中A柱子又作为“资源地”,C柱子又作为“辅助的柱子”,尽管这一步没有用到C柱子;

4.编程思想:递归

  1. 用递归的思想编程,分为三步:重复、变化、边界
  • 重复:把盘子不断的从资源地转移到目的地,同时要利用辅助的柱子第一次把n个盘子转移到目的地,但要先把n-1个盘子转移到辅助的柱子第二次n-1个盘子转移到目的地,但要先把n-2个盘子转移到辅助的柱子上;后面的以此类推;
  • 变化:资源地与辅助地所对应的柱子每一次都在互换n不断变小;
  • 边界:当n=1时,把最后一个盘子从资源地转移到目标地,并结束递归循环;

5.代码(Java)

/**
 * move(盘子个数,资源地,目的地,辅助地)
 */
public class Main {
    static int N=3;
    public static void main(String[] args) {
        //把n个盘子从A(资源地)柱转移到B(目的地)柱子上,C柱子作为“辅助的柱子”
        move(N,"A","B","C");
    }

    private static void move(int n, String A, String B, String C) {
        //n=1时,把最后一个盘子从A柱(资源地)转移到B柱(目的地)上,并结束递归
        if(n==1){
            System.out.println("把 "+n+" from "+A+" to "+B+","+C+" as a helper!");
            return;
        }
        //先把n-1个盘子从A柱(资源地)转移到C柱(目的地)上,B柱作为“辅助的柱子”
        move(n-1,A,C,B);
        //再把第n个盘子从A柱(资源地)转移到B柱(目的地)上,C柱作为“辅助的柱子”
        System.out.println("把 "+n+" from "+A+" to "+B+","+C+" as a helper!");
        //把n-1个盘子从C柱(资源地)转移到B柱(目的地)上,A柱作为“辅助的柱子”
        move(n-1,C,B,A);
    }
}

以上是我用递归方式求解汉诺塔问题的方法,希望对您有帮助。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值