汉诺塔

问题介绍

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
 
数学解法
 有n个盘子,和柱子x、y、z
 设把n个盘子从x移动到z所需步数N=f(n)
 那么,把n-1个盘子从x移动到y所需的步数为f(n-1),把n-1个盘子从y移动到z所需步数也为f(n-1)
 把n个盘子从x移动到z可以分解为:
    1)把n-1个盘子从x移动到y
    2)把1个盘子从x移动到z
    3)把n-1个盘子从y移动到z
 那么f(n)=f(n-1)+1+f(n-1)=2f(n-1)+1

 由f(n)=2f(n-1)+1
 得f(n)+1=2f(n-1)+2=2(f(n-1)+1)
 即
 f(n)+1=2(f(n-1)+1)
 同理
 f(n-1)+1=2(f(n-2)+1)
 f(n-2)+1=2(f(n-3)+1)
 ...
 f(3)+1=2(f(2)+1)
 f(2)+1=2(f(1)+1)
 将上面所有式子左右两边分别相乘得
 f(n)+1=2^(n-1)*2(f(1)+1)=2^n*(f(1)+1)=2^(n+1)
 f(n)=2^(n+1)-1
 即把n个盘子从x移动到z所需步数N=2^(n+1)-1

如果需要的是结果,那么通过数学分析就可以得到,如果需要知道执行步骤,那么就需要代码递归了

package com.zby;

/**
 * @author zby
 * @title Hanoi
 * @date 2019年6月13日
 * @description 汉诺塔
 */
public class Hanoi {

    private static int counter = 0;

    public static void main(String[] args) {
        remove(4, "X", "Y", "Z");
        System.out.printf("一共移动%d步", counter);
    }

    public static void remove(int floor, String source, String mid, String target) {
        if (floor == 1) {
            System.out.println("第" + ++counter + "次从" + source + "移动到" + target);
            return;
        }
        remove(floor - 1, source, target, mid);
        remove(1, source, mid, target);
        remove(floor - 1, mid, source, target);
    }
}

 结果

第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
一共移动15步
原文地址:https://www.cnblogs.com/zby9527/p/9679561.html