首页 > 其他分享 >汉诺塔

汉诺塔

时间:2023-07-25 11:02:29浏览次数:39  
标签:target mid remove source 汉诺塔 盘子 移动

问题介绍

法国数学家 爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神 梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的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步

 

标签:target,mid,remove,source,汉诺塔,盘子,移动
From: https://blog.51cto.com/u_14682436/6843356

相关文章

  • 汉诺塔(2题)
     题解:1#include<iostream>2#include<algorithm>3#include<cstdio>4#include<cmath>5#include<cstring>6#include<vector>7#include<map>8#include<stack>9#include<queue>10#......
  • 汉诺塔
    使用递归模拟N层汉诺塔的移动过程把N层塔从A移到C,分为三步:1.把A的N-1层移到B2.把A剩下最后一层移到C3.把B上的N-1层移到C使用递归只要解决N-1层问题就能解决全部问题。新建函数voidmove(intn,chara,charb,charc);n为层数,a为起始位置,b为缓冲位置,c为目标位......
  • 通天之汉诺塔
    通天之汉诺塔汉诺塔移动的次数是2^n-1,但是呢由于本题的n很大,所以要用到高精,考察高精度,来愉快的打一下吧(呜呜我一直觉得高精没啥用所以妹学#include<bits/stdc++.h>usingnamespacestd;longlongn,a[10000010],l=1;voidp()//高精度函数加法{for(inti=1;i<=l;i......
  • 汉诺塔(三)
    汉诺塔(三)3000 ms | 内存限制:655353在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧......
  • 汉诺塔问题
    移动步骤三根柱子A,B,C。A杆上有N个N>1N>1穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:*每次只能移动一个圆盘;大盘不能叠在小盘上面。解法一:使用递归分析:当只有一个时,只需把第一个盘从a移到c两个时,先把第一个盘从a移到b,再把第二个盘从a移到c,最......
  • 汉诺塔问题(递归)
    #include<iostream>usingnamespacestd;voidmove(intn,chara,charb,charc){ if(n==0) return; move(n-1,a,c,b); cout<<a<<"-->"<<c<<endl; move(n-1,b,a,c);}intmain(){ intn; chara='......
  • 汉诺塔VII 1997 (技巧+递推)
    汉诺塔VIITimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):1261    AcceptedSubmission(s):838ProblemDescriptionn个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列。......
  • 汉诺塔DP
    题目描述如果将课本上的汉诺塔问题稍做修改:给定N只盘子,3根柱子,但是允许每次最多移动相邻的M只盘子(当然移动盘子的数目也可以小于M),最少需要多少次?输入格式输入数据仅有一行,包括两个数N和M(0<=M<=N<=8)输出格式仅输出一个数,表示需要移动的最少次数 #in......
  • 汉诺塔递归
    法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的n片金片。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只......
  • 递归汉诺塔
    题目描述法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的n片金片。不论白天黑夜,总有一个僧侣在按照下面的法则移动这......