hanoi

汉诺塔-Hanoi

筅森魡賤 提交于 2020-03-02 06:18:40
1. 问题来源: 汉诺塔(河内塔)问题是印度的一个古老的传说。   法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。   后来,这个传说就演变为汉诺塔游戏,玩法如下:   (1). 有三根杆子A,B,C。A杆上有若干碟子   (2). 每次移动一块碟子,小的只能叠在大的上面   (3). 把所有碟子从A杆全部移到C杆上 2. 解题思路:   题中只给了三座塔,我们利用B塔将圆盘全部移动到在C塔。    为了将 N 个盘子从 A 移动到 C, 需要先将第 N 个盘子上面的 N-1 个盘子移动到 B 上,这样才能将第 N 个盘子移动到 C 上。   同理,为了将第 N-1 个盘子从 B 移动到 C 上,需要将 N-2 个盘子移动到 A 上,这样才能将第 N-1 个盘子移动到 C 上。   通过递归就可以实现汉诺塔问题的求解。 3. 源代码: 1 public class

Hanoi Tower 汉诺塔问题

﹥>﹥吖頭↗ 提交于 2020-02-25 01:14:36
Hanoi Tower 汉诺塔问题 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图)。有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求打印移动的步骤。 其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n – 1(有兴趣的可以自己证明试试看)。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C; 若n为奇数,按顺时针方向依次摆放 A C B。 (1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。 (2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。 (3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。

栈与递归

拜拜、爱过 提交于 2020-02-08 23:15:05
递归的经典案例 hanoi塔 思路: 移动n层hanoi塔 ①将n-1层先移动到B塔 ②把A移动到C ③把n-1层从B塔移动到C塔 步骤①: 1)将n-2层先移动到C塔 2)把A移动到B 3)把n-2层从C塔移动到B塔 步骤1): …… private static void hanoi ( int n , String A , String B , String C ) { if ( n == 1 ) System . out . println ( A + "->" + C ) ; else { hanoi ( n - 1 , A , C , B ) ; // 移动层数n-1,源塔A,目标塔B System . out . println ( A + "->" + C ) ; hanoi ( n - 1 , B , A , C ) ; // 移动层数n-1,源塔B,目标塔C } } 递归与非递归的转换 消除递归的原因 1、递归执行需要系统提供隐式栈实现递归,因此效率低 2、递归算法是一次执行完成的,再处理某些问题时不合适 3、有些语言不支持递归(FOR-TRAN) 递归转换成非递归的方法 一类,简单递归问题的转换,对于尾递归和单向递归的算法,可用循环结构的算法替代;另一类,将递归中隐式的栈机制转换成用户控制的栈,利用栈来存储参数。 简单递归问题 求阶乘:n! private

Java-方法的使用-递归求解汉诺塔问题

北战南征 提交于 2020-02-08 17:09:47
递归求解汉诺塔问题 ​ 汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。 并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。 问应该如何操作? 对问题的分析: 将n个盘子从A座上移到C座上可分解为以下三个步骤: (1)将A上的n-1个盘子借助C先移到B上; 递归方法分解为: · 将A上1个盘子从A移到C; · 将A上1个盘子从A移到B; · 将C上1个盘子从C移到B; (2)将A座上剩下的一个盘移到C座上; (3)将n-1个盘从B座借助于A座移到C座上; 递归方法分解为: · 将B上1个盘子从B移到A; · 将B上1个盘子从B移到C; · 将A上1个盘子从A移到C; 其中步骤(1)和步骤(3)都是将n-1个盘从一个座移到另一个座上,采取的办法一样,只是座的名字不同。为了使之一般化,可以将步骤(1)和步骤(2)表示为: 将“one”座上的n-1个盘移到“two”座(借助“three”座) 在步骤(1)中: one对应A,two对应B,three对应C 在步骤(3)中: one对应B,two对应C,three对应A 所以

Hanoi塔问题(经典数学问题+递归)

为君一笑 提交于 2020-01-29 00:38:20
问题描述: 这个问题起源于一个类似传说故事,在Hanoi这个地方有一个寺庙,这里有3根柱子和64个大小不同的金碟子。每个碟子有一个孔可以穿过。所有的碟子都放在第一个柱子上,而且按照从上到下碟子的大小依次增大的顺序摆设。如下图: 现在,假定寺庙里的僧侣要移动这些碟子,将它们从最左边移动到最右边的柱子上。不过移动的规则如下: 1. 每次只能从一个柱子的最上面移动一个碟子到另外一个柱子上。 2. 不能将大碟子放到小碟子的上面。 按照前面这个规则,我们该怎么去移动这些碟子呢?假定单位时间内可以移动一片碟子,那么最终移动这些碟子到目的柱子需要多长的时间呢? 问题分析: 在分析这个问题的时候,我们可以先从一些简单的场景来看怎么来移动碟子保证可以达到目的。假定我们有3个碟子,那么移动它们的过程如下图: 我们假定柱子从左到右分别为a, b, c。从前面移动碟子的步骤可以看到,我们要将a上面的两个碟子先移动到中间的b柱子作为过渡,然后再将最下面的柱子移动到目的c柱子,然后再将上面的两个碟子移过来。在将最下面的碟子移动到c之前,首先的步骤1, 2, 3是将上面的碟子移动到柱子b。而将最下面碟子移动后,上面的两个碟子又要移动一遍,不过是从b移动到c,只是借助的柱子不一样。 所以,从上面的过程,我们可以看到一个可以递归解决问题的思路,如下图: 如图所示,首先我们针对有n个碟子的柱子a,将n

Bailian4147 汉诺塔问题(Hanoi)

安稳与你 提交于 2019-12-18 13:51:53
4147:汉诺塔问题(Hanoi) 总时间限制: 1000ms 内存限制: 65535kB 描述 一、汉诺塔问题 有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘; 大盘不能叠在小盘上面。 提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。 问:如何移?最少要移动多少次? 汉诺塔示意图如下: 三个盘的移动: 二、故事由来 法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。 不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。这需要多少次移动呢?这里需要递归的方法。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不难证明f(n)=2

go实现汉诺塔

喜欢而已 提交于 2019-12-16 21:08:46
go实现汉诺塔 package main import ( "flag" "fmt" "strconv" ) var num int // 可输入汉诺塔层数 var Hanoi [3][]int var disks int = 0 func init() { flag.IntVar(&num, "num", 100, "The greeting object.") } func main() { flag.Parse() if (num <= 0) { fmt.Printf("%v \n", "参数必须大于0") return } for i := num; i > 0; i-- { Hanoi[0] = append(Hanoi[0], i) } echo() hanoi(num, 0, 1, 2) } func move( from int, to int) { disks++ length := len(Hanoi[from]) Hanoi[to] = append(Hanoi[to], Hanoi[from][length-1]) Hanoi[from] = append(Hanoi[from][:length-1]) echo() } func hanoi(n int, A int, B int, C int) { if (n == 1) { move( A, C); }

Hanoi塔问题

徘徊边缘 提交于 2019-12-08 20:28:29
汉诺塔问题#include <iostream> using namespace std; void Hanoi(int n, char src, char mid, char dest ) //将src上的盘子以mid为中转移动到dest { if (n == 1){ cout << src << "-->" << dest <<endl; return; } //如果只有一个盘子,那么直接从src移动到dest即可 Hanoi(n-1, src, dest, mid); //先将n-1个盘子从src移动到mid,以dest为中转 cout << src << "-->" << dest <<endl; //再将最大的一个盘子从src直接移动到dest Hanoi(n-1, mid, src, dest); //最后将n-1个盘子从mid移动到dest,以src为中转 } int main(){ int n; cin >> n; Hanoi(n, 'A', 'B', 'C'); return 0; } 来源: https://www.cnblogs.com/fzu-jpy/p/12007042.html

go实现汉诺塔

ぃ、小莉子 提交于 2019-12-06 02:51:01
go实现汉诺塔 package main import ( "flag" "fmt" "strconv" ) var num int // 可输入汉诺塔层数 var Hanoi [3][]int var disks int = 0 func init() { flag.IntVar(&num, "num", 100, "The greeting object.") } func main() { flag.Parse() if (num <= 0) { fmt.Printf("%v \n", "参数必须大于0") return } for i := num; i > 0; i-- { Hanoi[0] = append(Hanoi[0], i) } echo() hanoi(num, 0, 1, 2) } func move( from int, to int) { disks++ length := len(Hanoi[from]) Hanoi[to] = append(Hanoi[to], Hanoi[from][length-1]) Hanoi[from] = append(Hanoi[from][:length-1]) echo() } func hanoi(n int, A int, B int, C int) { if (n == 1) { move( A, C); }

双色Hanoi塔问题

荒凉一梦 提交于 2019-12-03 03:21:56
双色Hanoi塔问题 【问题描述】 设A、B、C是3 个塔座。开始时,在塔座A 上有一叠共n 个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为1,2,……,n,奇数号圆盘着蓝色,偶数号圆盘着红色,如图所示。现要求将塔座A 上的这一叠圆盘移到塔座B 上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则: 规则(1):每次只能移动1 个圆盘; 规则(2):任何时刻都不允许将较大的圆盘压在较小的圆盘之上; 规则(3):任何时刻都不允许将同色圆盘叠在一起; 规则(4):在满足移动规则(1)-(3)的前提下,可将圆盘移至A,B,C 中任一塔座上。 试设计一个算法,用最少的移动次数将塔座A 上的n个圆盘移到塔座B 上,并仍按同样顺序叠置。 【编程任务】 对于给定的正整数n,编程计算最优移动方案。 【输入格式】 由文件hanoi.in给出输入数据。第1 行是给定的正整数n。 【输出格式】 将计算出的最优移动方案输出到文件hanoi.out。文件的每一行由一个正整数k和2个字符c1和c2组成,表示将第k个圆盘从塔座c1移到塔座c2上。 【输入样例】 3 【输出样例】 1 A B 2 A C 1 B C 3 A B 1 C A 2 C B 1 A B #include #include using namespace std; int k=0,n,i; int f1[1200]