17.11.9 汉诺塔问题

描述
汉诺塔是约19世纪末,在欧州的商店中出售一种智力玩具。它的结构如下图所示: 
 
在一个平板上立有三根铁针,分别记为A, B, C。开始时,铁针 A 上依次叠放着从大到小 n 个圆盘,游戏的目标就是将 A 上的 n 个圆盘全部转移到 C 上,要求每次只能移动某根铁针最上层一个圆盘,圆盘不得放在这三根铁针以外的任何地方,而且永远只能将小的圆盘叠放在大的圆盘之上。

例如,下面就是示例输出中(n = 3)移动方案的图示:

这是一个著名的问题,几乎所有的教材上都有这个问题。由于条件是一次只能移动一个盘,且不允许大盘放在小盘上面,所以 64 个盘的移动次数是: 
18,446,744,073,709,551,615 
这是一个天文数字,若每一微秒可能做一次移动,那么也需要几乎一百万年。我们仅能找出问题的解决方法并解决较小 n 值时的汉诺塔,但很难用计算机解决64层的汉诺塔。


关于输入
输入数据只有一个正整数 n (n <= 16) , 表示开始时铁针 A 上的圆盘数


关于输出
要求输出步数最少的搬动方案,方案是由若干个步骤构成的,输出的每行就表示一个移动步骤,例如,“A->B”就表示把铁针 A 最上层的一个圆盘移动到 B 上。


例子输入
3
例子输出
A->C
A->B
C->B
A->C
B->A
B->C
A->C

 1 #include <iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int f(int i,char a,char b,char c)    //定义一个函数为i个圆盘从a经过b全部套到a上的函数
 5 {
 6     if (i == 1)           //最基本的状态
 7         cout << a << "->" << c<<endl;
 8     else         //递归
 9     {
10         f(i - 1, a, c, b);
11         cout << a << "->" << c<<endl;
12         f(i - 1, b, a, c);
13     }
14     return 0;       //返回值
15 }
16 int main()
17 {
18     int n;
19     cin >> n;
20     char a = ‘A‘, b = ‘B‘, c = ‘C‘;
21     f(n, a, b, c);
22 }

初识函数,初识递归,有种耳目一新的感觉,代码还能这么用,太方便了

一开始完全没有头绪,想得十分复杂,之后才发现计算机比我想象的能干得多

学习了
时间: 2024-11-08 19:38:22

17.11.9 汉诺塔问题的相关文章

[18/11/24] 汉诺塔问题

问题描述:要求将A柱子上的盘子移动到C柱子上,移动过程中大盘子不能在小盘子下边(即必须满足大盘在下,小盘在上),求移动步骤? 示例:若A上只有1号和2号这2个盘子,移动步骤 A(2)-->>B,   A(1)-->>C ,  B(2)-->>C  [A(2)表示柱子A上的2号盘子] 思想:用递归(以3个盘子为例) 1.若只有1个盘子,直接将他从A柱子上移动到C柱子上: 2.若有n个盘子(假设n=3,即有3个盘子),可以考虑先划分为2个部分,构成大问题.即最下边的1号盘子

汉诺塔问题(用栈替代递归)

汉诺塔问题 古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图).有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求输出移动的步骤. 汉诺塔问题递归解法 C++代码 1 //By LYLtim 2 //2015.2.8 3 4 #include <iostream> 5 6 using namespace std; 7 8 void ha

17.图形化实现汉诺塔

1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <stdarg.h>//标准参数 6 7 int a[10][3] = { 0 }; 8 int buzou = 1;//表示步骤数 9 10 //初始化 11 void init(int a[10][3],int num) 12 { 13 for (int i = 0; i < num

2017.11.26 计算机算法之分治与递归——汉诺塔

1.我的递归算法(纯粹的递归) #include <stdio.h>//当盘子数n等于15时,移动次数已经达到32767,运行时间已经达到15.540s long long count; void hanoi(int n,char a,char b,char c)//借助C将A上的盘子全部移动到B { if(n==0) return; hanoi(n-1,a,c,b); printf("%c --> %c\n",a,b); count++; hanoi(n-1,c,b

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

汉诺塔的递归算法与解析

从左到右 A  B  C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面. 如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号. 小时候玩过这个游戏, 基本上玩到第7个,第8个就很没有耐心玩了,并且操作的动作都几乎相同觉得无聊.  后来学习编程, 认识到递归, 用递归解决汉诺塔的算法也是我除了简单的排序算法后学习到的第一种算法. 至于递归,简单来说

汉诺塔VII(递推,模拟)

汉诺塔VII Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1503 Accepted Submission(s): 1077   Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从

汉诺塔递归实现

经典问题汉诺塔的实现中,递归实现可以说是代码量最少,并最简单易懂的实现方法了. 假设有三根柱子a,b,c.其中a柱子上有n个金片.我们的目的就是把n个金片借助b,全部移动到c上.这是一个汉诺塔问题. 这个问题可以分解成如下子问题: (1)将n-1个金片从a移动到b.这又是一个汉诺塔问题. (2)上面执行完之后,可以直接将第n个金片移动到c. (3)上面两步执行完之后,将n-1个金片从b移动到c.这又再次是一个汉诺塔问题. 很显然,把上面的步骤翻译成递归形式可以得到如下的程序: 1 #includ

【汉诺塔问题】UVa 10795 - A Different Task

[经典汉诺塔问题] 汉诺(Hanoi)塔问题:古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求打印移动的步骤.如果只有一个盘子,则不需要利用B座,直接将盘子从A移动到C. 如果有2个盘子,可以先将盘子1上的盘子2移动到B:将盘子1移动到c:将盘子2移动到c.这说明了:可以借助B将2个盘子从A移