汉诺塔

汉诺塔的图解递归算法

断了今生、忘了曾经 提交于 2019-11-30 23:27:30
转自: https://www.cnblogs.com/dmego/p/5965835.html https://dmego.me/2016/10/16/hanoi 一.起源:   汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 二.抽象为数学问题:   如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数 解:(1)n == 1       第1次 1号盘 A---->C sum = 1 次 (2) n == 2       第1次 1号盘 A---->B        第2次 2号盘 A---->C       第3次 1号盘 B---->C sum = 3 次   (3)n == 3         第1次 1号盘 A---->C         第2次 2号盘 A---->B         第3次 1号盘 C---->B         第4次 3号盘 A---->C        

汉诺塔算法

杀马特。学长 韩版系。学妹 提交于 2019-11-30 21:15:30
有A、B和C 3跟柱子,在A上从下往上按照从小到大的顺序放着64个圆盘,以B为中介,把盘子全部移动到C上。移动过程中,要求任意盘子的下面要么没有盘子,要么只能有比它大的盘子。 * 思想:采用递归的方法来接 * 1. 先将A上面的n-1个盘子,移到B柱上 * 2. 然后把A上最大的一个盘子放到C上去 * 3. 然后把B上面的n-1个盘子移到A上去 * * 步骤: * 汉若塔用递归思考首先考虑一种临界状态,把n-1个上面的盘从A—B, 就是把n从A移动到C,最后把n-1个盘从B---C, * (注意在考虑把n-1个盘从B---C的时候就出现递归调用,如果把A,B盘交换就又重复上面的流程了,最后到n = 1的时候就返回) * * 伪代码: * public void run(int n, char a, char b, char c) { if(n==1) { move(n,a,c) //等于1的时候把盘从A移动到C }else { run(n-1,a,b,c);//递归调用把a上面的n-1个盘移动到B上,怎么表示移动?把柱子交换不就是移动了。 move(n,a,c); run(n-1,b,a,c);//意图是把n-1个盘从B移动到A上。 } } * package cglib; import java.io.BufferedReader; import java.io

[python]汉诺塔问题

[亡魂溺海] 提交于 2019-11-30 12:55:46
相传在 古印度 圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。 (1)以C盘为中介,从A杆将1至n-1号盘移至B杆; (2)将A杆中剩下的第n号盘移至C杆; (3)以A杆为中介;从B杆将1至n-1号盘移至C杆。 递归: 1 #p6_9..py 2 #汉诺塔 3 def hanoi(n,x,y,z): 4 if n==1: 5 print(x,'-->',z) 6 else: 7 hanoi(n-1,x,z,y) 8 print(x,'-->',z) 9 hanoi(n-1,y,x,z) 10 n=int(input('请输入汉诺塔的层数:')) 11 hanoi(n,'X','Y','Z') 来源: https://www.cnblogs.com/zlc364624/p/11589742.html

SDUTOJ 1200 - 汉诺塔 (java实现)

别来无恙 提交于 2019-11-30 11:57:31
汉诺塔 Problem Description 汉诺塔(又称河内塔)问题是印度的一个古老的传说。 开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒A、B和C,A上面套着n个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从A棒搬到C棒上,规定可利用中间的一根B棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。 僧侣们搬得汗流满面,可惜当n很大时这辈子恐怕就很搬完了。 聪明的你还有计算机帮你完成,你能写一个程序帮助僧侣们完成这辈子的夙愿吗? Input 输入金片的个数n。这里的n<=10。 Output 输出搬动金片的全过程。格式见样例。 Sample Input 2 Sample Output Move disk 1 from A to B Move disk 2 from A to C Move disk 1 from B to C Hint 可以用递归算法实现。 Source 注:提交时WA多次,最后删除 package test才能AC,至于为啥,目前还不知道 package test import java . util . Scanner ; import java . lang . Math ; public class Main { public static void hanoi ( int n , char a ,

学习python的第三天笔记

扶醉桌前 提交于 2019-11-30 03:25:44
18、024 递归:汉诺塔 def hanoi(n,x,y,z): if n == 1: print(x,'->',z) else: hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上 print(x,'->',z)#将最底下的一个盘子从x移动到z上 hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上 n = int(input('请输入汉诺塔的层数:')) hanoi(n,'x','y','z') 19、025 值(value) 字典是印射存在的,例如:dict1 = {'小明':'我爱你','小米':'为发烧而生','小马':'爱老虎油'} print('小米说:',dict1['小米']) 小米说: 为发烧而生 字典的创建方式,例如:dict2 = dict((('a',65),('b',66),('c',67))) dict3 = dict(小米='为发烧而生',小新='为你而改变') 字典的修改,例如:dict3['小新'] = '信你个鬼' dict3 {'小米': '为发烧而生', '小新': '信你个鬼'} 如果索引的是没有的,会直接添加入字典里。 20、026 字典 #.fromkeys(())可以添加值,例如:dict1={} dict1.fromkeys((1,2,3),'number') {1: 'number', 2:

汉诺塔

 ̄綄美尐妖づ 提交于 2019-11-29 19:47:39
汉诺塔-(三柱,四柱) 背景: 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 三柱: 1 #include<bits/stdc++.h> 2 using namespace std; 3 int sum = 0; 4 void move(int n,char a,char b) 5 { 6 sum++; 7 printf("%d ,%c -> %c\n",n,a,b); 8 } 9 void han(int n,char a,char b,char c) 10 { 11 if(n>0) 12 { 13 han(n-1,a,c,b); 14 move(n,a,b); 15 han(n-1,c,b,a); 16 } 17 18 } 19 int main() 20 { 21 han(5,'a','b','c'); 22 printf("%d",sum); 23 } 来源: https://www.cnblogs.com/GhostRiderQin/p/11530561.html

函数使用

夙愿已清 提交于 2019-11-29 12:31:53
       函数使用 为什么要使用函数 ? 一个较为复杂的系统往往需要若干个子系统,然后分别对这些子系统进行开发。通常将相对独立的,经常使用的功能抽象为函数,函数编写好以后可以被重复利用,这样有利于代码重用,提升开发效率,增强程序可靠性,也便于分工合作和修改。 ---c++语言程序设计函数部分     从上面这段话中我们可以提炼出使用函数的几个优点! 代码重复利用 代码分区分块,便于修改和维护 增强程序的可靠性 下面我就用一个简单的打印程序来说明函数的方便性。 #include <iostream> using namespace std; void print(int a) { cout << a << endl; } int main() { int a, b,sum; a = 3, b = 4; sum = a + b; print(sum); sum = b - a; print(sum); return 0; } 这段代码就体现了函数的分块性和代码重复利用性,每当我看一下代码计算过程的值,我就调用一下 print 函数,就不需要在反复写cout语句了,其次打印函数和主函数是分开的,维护起来只用看有问题的部分,互不影响。   为什么要用函数重载 ? 两个以上的函数,具有相同的函数名,但是形参的个数或者类型不同,编译器根据实参和形参类型及个数的最佳匹配

汉诺塔III HDU - 2064

安稳与你 提交于 2019-11-29 12:09:08
汉诺塔III HDU - 2064 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。 现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。 Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边? Input包含多组数据,每次输入一个N值(1<=N=35)。Output对于每组数据,输出移动最小的次数。Sample Input 1 3 12 Sample Output 2 26 531440 1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<queue> 5 6 using namespace std; 7 8 long long F(int num) // 返回值较大时使用long long 9 { 10 if(num == 1) 11 return 2; 12 return 3*F(num-1)+2; 13 } 14

AcWing - 96 - 奇怪的汉诺塔 = dp

自古美人都是妖i 提交于 2019-11-29 10:30:12
https://www.acwing.com/problem/content/98/ 先考虑三个柱子的汉诺塔问题,设d[i]表示在三个柱子都可以选时,把i个塔从一个柱子移动到另一个柱子的最小移动步数。首先把n-1个塔从A移动到B,然后把n从A移动到C,再把n-1个塔从B移动到C。 d[i]=2*d[i-1]+1 当有四个柱子时,情况稍微改变,设f[i]表示在四个柱子都可以选时,把i个塔从一个柱子移动到另一个柱子的最小移动步数,但是观察到实际上最底层的n-j个塔都是要从A到D的,而其中B和C之一必然要把顶层的塔全部放上才空出另一个塔给n-j中转(当然如果只有n一个的话是不需要中转的)。 所以先把j个塔在四个柱子的情况从A移动到B,然后ACD三个塔把n-j从A移动到D,再把j个塔在四个柱子的情况从B移动到D。 f[i]=min(f[i],2*f[j]+d[n-j]) 貌似可以推广到更多柱子。 来源: https://www.cnblogs.com/Inko/p/11515577.html

Acwing-96-奇怪的汉诺塔(递推)

核能气质少年 提交于 2019-11-29 05:08:39
链接: https://www.acwing.com/problem/content/description/98/ 题意: 汉诺塔问题,条件如下: 1、这里有A、B、C和D四座塔。 2、这里有n个圆盘,n的数量是恒定的。 3、每个圆盘的尺寸都不相同。 4、所有的圆盘在开始时都堆叠在塔A上,且圆盘尺寸从塔顶到塔底逐渐增大。 5、我们需要将所有的圆盘都从塔A转移到塔D上。 6、每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。 请你求出将所有圆盘从塔A移动到塔D,所需的最小移动次数是多少。 思路: 汉诺塔问题的递推式为D[i] = 2*D[i-1]+1.表示先用三个塔将n-1个盘子移到中间,在将一个盘子移到最后,在将n-1个盘子移到最后. 而四个柱子.可以先用四根柱子将j个盘子移到第二根,在将n-j个盘子移到最后一根,在通过四个柱子将j个盘子移到最后一个. 代码: #include <bits/stdc++.h> using namespace std; int D[20]; int F[20]; int main() { for (int i = 1;i <= 12;i++) D[i] = 2*D[i-1]+1; memset(F, 0x3f3f3f, sizeof(F)); F[0] = 0; for (int i = 1;i <= 12;i