讨论汉诺塔之谜

汉诺塔是数学上的一个谜题。有三根杆子,一些不同大小的中间有孔的圆盘,可以按大小顺序套在杆子上,最小的在最上面,堆成类似锥形的结构。问题是怎么把一根杆子上的一堆圆盘移动到另一根杆子上,限定条件如下:

一次只能移动一个圆盘。

每一次移动步骤包括将一根杆子最上面的圆盘移开放到另一根杆子上圆盘的最上层(不能动下面的盘子)。

所有大圆盘的下面不能有比他小的圆盘。

算法步骤(有n个圆盘,三根杆子分别为A,B,C,要将所有盘子从A上移动到B上)

将A上面的n-1个圆盘移动到C上。

将A上面最后一个圆盘移动到B上。

将C上面的n-1个圆盘移动到B上。

从C上移动n-1个圆盘到B上我们如法炮制。一旦我们解决n=3的情况,我们就能解决任何数量的盘子了。

void towerOfHanoi(int n, char fromPeg, char toPeg, char auxPeg)
{
    //If only one disk, make a move and return :: base case
    if(n == 1)
    {
        printf("Move disk 1 from peg %c to peg %c ",fromPeg, toPeg);
        return;
    }
    //Move top n-1 disks from A to B, using C as auxiliary
    towerOfHanoi(n-1, fromPeg, auxPeg, toPeg);

    //Move remaining disks from A to C
    printf("\nMove disk %d from peg %c to peg %c ",n, fromPeg, toPeg);

    //Move n-1 disks from B to C using A as the auxiliary
    towerOfHanoi(n-1, auxPeg, toPeg, fromPeg);
}

假设我们传递这样的参数:

towerOfHanoi(3, ‘A‘. ‘B‘, ‘C‘);

输出如下:

Move disk 1 from peg A to peg B
Move disk 2 from peg A to peg C
Move disk 1 from peg B to peg C
Move disk 3 from peg A to peg B
Move disk 1 from peg C to peg A
Move disk 2 from peg C to peg B
Move disk 1 from peg A to peg B

注:代码不长,但理解代码的运行过程可能需要动一些脑筋,我在最后附上完整代码,或许你需要参考我前面的内容递归和内存分配(可视化)

#include<stdio.h>
#include<stdlib.h>
/*
Code obtained from

http://www.studyalgorithms.com
*/
void towerOfHanoi(int n, char fromPeg, char toPeg, char auxPeg)
{
    //If only one disk, make a move and return :: base case
    if(n == 1)
    {
        printf("Move disk 1 from peg %c to peg %c \n",fromPeg, toPeg);
        return;
    }
    //Move top n-1 disks from A to B, using C as auxiliary
    towerOfHanoi(n-1, fromPeg, auxPeg, toPeg);

    //Move remaining disks from A to C
    printf("Move disk %d from peg %c to peg %c \n",n, fromPeg, toPeg);
    /*
    Feel free to copy but please acknowledge studyalgorithms.com
    */

    //Move n-1 disks from B to C using A as the auxiliary
    towerOfHanoi(n-1, auxPeg, toPeg, fromPeg);
}

int main(void)
{
    printf("Enter the number of disks:- ");
    int disks;
    scanf("%d",&disks);
    towerOfHanoi(disks,‘A‘,‘B‘,‘C‘);
    return 0;
}
时间: 2024-08-29 00:17:56

讨论汉诺塔之谜的相关文章

算法学习(4)----汉诺塔递归算法和非递归算法

学习<算法设计与分析基础>,习题2.4 第5题要求为汉诺塔游戏设计一个非递归的算法. 思,不得其解.看书后答案提示: 你如果做不到,也不要沮丧:这个问题的非递归算法虽然不复杂,但却不容易发现.作为一种安慰,可以在因特网上寻找答案. 好吧,话都说得这么直接了,遂百度之,得到一个感觉很好的答案,略做修改,摘录于下: 原文地址:http://blog.sina.com.cn/s/blog_48e3f9cd01000474.html ##################################

多柱汉诺塔最优算法

转自Florian 1. 三柱汉诺塔三柱汉诺塔是经典的汉诺塔问题,在算法设计中是递归算法的典型问题.其算法是这样的: 首先把A 柱上面的n- 1 个碟子通过C 柱移到B 柱上[T(n-1)步],然后把A 柱剩下的一个碟子移到C 柱上[1步], 最后把B 柱上所有的碟子通过A 柱移到C 柱上[T(n-1)步].很容易得到算法的递归方程为:T(n)=2*T(n-1)+1,因此,不难算出步数是T(n)=2^n-1.对于三柱汉诺塔的算法的正确性自然是毫无争议的,我们需要的是从三柱汉诺塔的设计中引申出多柱

用栈来求解汉诺塔问题

当然.这是一个经典的递归问题~   想必来看这篇博文的同学对汉诺塔应该不会陌生了吧, 写这篇博还是有初衷的: 之前学数据结构的时候自己看书.也上网上查了很多资料,资料都比较散.而且描述的不是很清楚,对于当时刚刚 接触算法的我,要完全理解还是有一定难度.今天刚好有时间就整理了下思路.重写分析了一下之前的疑惑的地方. 没有透彻的地方便都豁然开朗了.所以迫不及待把我的想法记录下来,和大家分享. 如果你也是和之前的我一样对hanoi tower没能完全消化,或者刚刚接触汉诺塔,那希望我的这种理解方式能给

汉诺塔算法之求解最佳步数

写的不好,但是请尊重版权,转载请注明出处: http://www.cnblogs.com/xiaovw/ 何为汉诺塔? 答:汉诺塔是根据一个传说形成的一个问题.汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 关于汉诺塔的经典问题: 有三根相邻的柱子,标号为A,

汉诺塔(三)_栈的应用

问题 E: 汉诺塔(三) 时间限制: 3 Sec  内存限制: 128 MB提交: 2  解决: 2[提交][状态][讨论版] 题目描述 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔.不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面.僧侣们预言,当所有的金片都从梵天穿好的那根针上移

汉诺塔问题的递归实现

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 1.汉诺塔(基本) 汉诺塔问题是典型的分治算法问题,首先我们来讨论最基本的汉诺塔问题.假设有n个圆盘,三根柱子,a,b,c,需要把n个盘子(从上往下从小到大摞着)从a柱移动到c柱,在小圆盘上不能放大圆盘,在三根柱

新版汉诺塔(UVa10795 - A Different Task)

题目介绍: 标准的汉诺塔上有n个大小各异的盘子.现给定一个初始局面(见图1),求它到目标局面(见图2)至少需要移动多少步? 移动规则:一次只能移动一个盘子:且在移动盘子之前,必须把压在上面的其他盘子先移走:基于汉诺塔问题的原始约定,编号大的盘子不得压在编号小的盘子上. Sample Input 3 1 1 1 2 2 2 3 1 2 3 3 2 1 4 1 1 1 1 1 1 1 1 0 Sample Output Case 1: 7 Case 2: 3 Case 3: 0 问题分析: 为了更好

【BZOJ 1019】 [SHOI2008]汉诺塔

1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 880  Solved: 540 [Submit][Status] Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的盘子一定放在比它更

bzoj千题计划109:bzoj1019: [SHOI2008]汉诺塔

http://www.lydsy.com/JudgeOnline/problem.php?id=1019 题目中问步骤数,没说最少 可以大胆猜测移动方案唯一 (真的是唯一但不会证) 设f[i][j] 表示 从i号柱子 上把j个盘子移到 g[i][j] 柱子上的步数 初始化:f[0][1]=1,g[0][1] 根据优先级决定 设三根柱子分别为0,1,2 对于每一个f[x][i], 把前i-1个移走,把第i个移走,把前i-1个移回 令y=g[x][i-1],则k=0+1+2-x-y 我们希望 把i-