算法初步
约 656 字大约 2 分钟
2026-06-29
排序
散列
递归
汉诺塔
点击展开题目 汉诺塔
汉诺塔(又称河内塔)问题源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
抽象成模型就是说:
有三根相邻的柱子,标号分别为A、B、C,A柱子按金字塔状叠放着n个不同大小的圆盘,现在要把所有盘子一个一个移动到柱子C上,并且任何时候同一根柱子上都不能出现大盘子在小盘子上方,请问至少需要多少次移动,并给出具体的移动方案。
输入描述: 一个正整数n(1≤n≤16),表示圆盘的个数。
输出描述: 第一行输出一个整数,表示至少需要的移动次数。
接下来每行输出一次移动,格式为X->Y,表示从柱子X移动最上方的圆盘到柱子Y最上方。
输入样本:
1样本输出:
1
A->C代码长度限制[待补充] KB | 时间限制[待补充] ms | 内存限制[待补充] MB | 栈限制[待补充] KB
思路 该问题运用递归思想求解。 将n个盘子从A柱移到C柱,可拆解为三个步骤: 先把上面n−1个小盘从A移到B,这需要Sn−1次; 接着把最底下最大的1个盘子从A移到C,需1次; 最后把n−1个小盘从B移到C,又需Sn−1次。 由此得到总步数公式Sn=2⋅Sn−1+1,初始条件S1=1,进而推出通项公式Sn=2n−1。在具体移动过程中,大盘的移动操作必须夹在两次小盘搬运中间,以保证符合规则。
C++
#include <bits/stdc++.h>
using namespace std;
int n;
void f(int n, char from, char to, char mid)
{
if(n == 0) return;
else
{
f(n - 1, from, mid, to);
printf("%c->%c\n", from, to);
f(n - 1, mid, to, from);
}
}
int main()
{
cin >> n;
cout << pow(2, n) - 1 << "\n";
f(n, 'A', 'C', 'B');
return 0;
}Java
[待补充]Python
[待补充]