zoukankan      html  css  js  c++  java
  • 汉诺塔(Hanoi)——小小算法

    传送门: 袁咩咩的小小博客

    汉诺(Hanoi)塔源于古印度,是非常著名的智力趣题,大意如下:

    勃拉玛是古印度的一个开天辟地的神,其在一个庙宇中留下了三根金刚石的棒,第一
    根上面套着64个大小不一的圆形金片。其中,最大的金片在最底下,其余的依次叠上
    去,且一个比一个小。勃拉玛要求众僧将该金刚石棒中的金片逐个地移动到另一根棒
    上,规定:
        一次只能移动一个金片,且金片在放到棒上时,只能大的放在小的下面,但是可以利用中间的一根棒最为辅助。
    

    问题分析


    从上至下,我将盘一次标号为1、2、3......

    • 当只有一个盘的时候,只需要将其从A棒移动至C棒;

    步骤:

    1号:A ——> C

    • 当有两个盘时,需要先将第一个盘移动至B棒,再将第二个盘移动至C棒,再将第一个盘移动至C棒;

    步骤:

    1号:A ——> B

    2号:A ——> C

    1号:B ——> C

    • 当有3个盘子时,需要进行的步骤为:

    1号:A ——> C

    2号:A ——> B

    1号:C ——> B

    3号:A ——> C

    1号:B ——> A

    2号:B ——> C

    1号:A ——> C


    可以看出,当号数与盘子总数相等时,进行的操作只有A ——> C。所以可以将把A棒上的所有盘子借助B棒移动到C棒的整个过程总结为三步:

    1. 将A棒上的n-1个圆盘借助C棒移动到B棒上
    2. 将A棒上的一个圆盘移动到C棒上
    3. 将B棒上的圆盘借助A棒移动到C棒上

    当然,当只有一个盘子时只需A ——> C;两个盘子的时候,也不需要中介。

    初态:
    image
    移动n-1个圆盘:
    image
    移动剩下的一个盘:
    image
    移动B棒上的盘:
    image

    示例代码

    package com.yuanyang.example;
    
    import java.util.Scanner;
    
    public class Hanoi {
    
        static long count;  //移动的次数
    
        /**
         * @param n 盘子总数
         * @param a A棒
         * @param b B棒
         * @param c C棒
         * @param disk 用来输出移动的第k个盘子
         */
        static void move(int n,char a,char b,char c,int disk){//A棒借助B棒移动到C棒
            disk --;
            if (n==1) {//当只有一个盘子的时候,直接从A棒移动至C棒
                System.out.printf("第%d次移动:	第%d个盘子,圆盘从%c移动到%c棒
    ",++count,disk,a,c);
            }else {//当盘子大于一的时候。
                move(n-1,a,c,b,disk);//将A棒上的n-1个盘子借助C棒移动到B棒
                System.out.printf("第%d次移动:	第%d个盘子,圆盘从%c移动到%c棒
    ",++count,disk,a,c);//将最后一张盘子从A棒移到C棒
                move(n-1,b,a,c,disk);//将B棒上剩下的n-1个盘子借助A棒移动到C棒
            }
        }
    
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            System.out.println("请输入圆盘数:");
            int n = input.nextInt();
            move(n,'a','b','c',n + 1);
            System.out.printf("一共进行了%d次移动
    ",count);
        }
    }
    

    这样,我们就可以得到结果了。但是,可以发现,移动的次数n和盘子数x存在 x = 2^n-1 的关系,所以,当盘子达到64个的时候,次数达到了18446744073709551615次,这就很尴尬了,这群僧人估计搬完是没戏了。

  • 相关阅读:
    Luogu3952 NOIP2017D1T2 时间复杂度
    Luogu4933 大师
    Luogu1966 火柴排队
    Luogu2881 排名的牛Ranking the Cows
    Luogu1439 最长公共子序列(LCS)
    Liferay7 BPM门户开发之20: 理解Asset Framework
    提高Liferay7的启动和运行速度
    liferay中jsonws的认证方法
    让Liferay的Service Builder连接其他数据库
    Liferay表结构介绍(四):Portlet相关表
  • 原文地址:https://www.cnblogs.com/yuanmiemie/p/6638664.html
Copyright © 2011-2022 走看看