汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔问题:古代有一个梵塔,塔内有三个柱子A、B、C,A柱子上有若干个盘子,盘子大的在下,小的在上,目标是要将这若干个盘子从A柱移到C柱,但每次只能允许移动一个盘子,并且在移动过程中,3个柱子上的盘子始终保持小盘在上,大盘在下,在移动过程中可以利用其他柱子,要求打印移动的步骤。
汉诺塔问题是使用递归解决问题的经典算法。
算法:
(1)当A柱子上只有一个盘子时,只需将A柱子上的一个盘子直接移到C柱子上即可;
(2)当A柱子上有两个盘子时,先将A柱子上的1号盘子(编号从上到下)移动到B柱子上,再将A柱子上的2号盘子移动的C柱子上,最后将B柱子上的小盘子移动到C柱子上;
(3)当A柱子上有3个盘子时,先将A柱子上编号1至2的盘子(共2个)移动到B柱子上(需借助C柱子),然后将A柱子上的3号最大的盘子移动到C柱子,最后将B柱子上的两个盘子借助A柱子移动到C柱子上;
(4)当A柱子上有n个盘子时,先将A柱子上编号1至n-1的盘子(共n-1个)移动到B柱子上(借助C柱子),然后将A柱子上最大的n号盘子移动到C柱子上,最后将B柱子上的n-1个盘子借助A柱子移动到C柱子上。
综上所述,除了只有一个盘子时不需要借助其他柱子外,其余情况都需要借助中间的柱子。
#include<iostream>
using namespace std;
void move(int i, char a, char b)
{
cout << "将盘" << i << "从" << a << "移动到" << b << endl;
}
void HanNuoTa(int n, char a, char b, char c)//a为起始柱子,b为中间柱子,c为目标柱子
{
if (n == 1)
move(1, a, c); //只有一个盘子是直接将起始柱子上的盘子移动到目标柱子上
else
{
HanNuoTa(n - 1, a, c, b); //先将初始柱子上的前(n-1)个盘子借助目标柱子移动到中间柱子上
move(n, a, c); //将剩下的第n个盘子移动到目标柱子上
HanNuoTa(n - 1, b, a, c); //最后将中间柱子上的(n-1)个盘子移动到目标柱子上
}
}
int main()
{
int n ;
char a = 'A';
char b = 'B';
char c = 'C';
cout << "请输入盘子的个数:" << endl;
cin >> n;
HanNuoTa(n, a, b, c);
system("pause");
return 0;
}