半年多前遇到的问题,经过半年已经忘记递归怎么用了。
今天重新遇到发现毫无头绪,看了题解才发现原来是这样。
果然还是一点都不熟悉递归。
题目:
汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题。在A,B,C三根柱子上,有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我A上(如图所示),你的目标是在最少的合法移动步数内将所有盘子从A塔移动到C塔。
游戏中的每一步规则如下:
1. 每一步只允许移动一个盘子(从一根柱子最上方到另一个柱子的最上方)
2. 移动的过程中,你必须保证大的盘子不能在小的盘子上方(小的可以放在大的上面,最大盘子下面不能有任何其他大小的盘子)
如对于n=3的情况,一个合法的移动序列式:
1 from A to C
2 from A to B
1 from C to B
3 from A to C
1 from B to A
2 from B to C
1 from A to C
给出一个数n,求出最少步数的移动序列
考虑n个的情况,首先将n-1个盘子从A通过C移到B,然后将第n个(最后一个,最大的盘子)从A到C,再将剩下的n-1个盘子从B通过A移到C。
代码参考了网上的题解:
#include <iostream>
#include <cmath>
#include <string>
#include <algorithm>
using namespace std;
void move(int n, char from, char to) {
cout << n << " from " << from << " to " << to << endl;//n从from移到to
}
void hanoi(int n, char from, char borrow, char to) {
if(n == 1) move(n, from, to);
else {
hanoi(n - 1, from, to, borrow);//n-1个盘子通过借用塔(C塔)从from(A)移动到to(B)
move(n, from, to);//第n个从from移动到to
hanoi(n - 1, borrow, from, to);//n-1个盘子通过借用塔(A塔)从from(B)移动到to(C)
}
}
int main() {
int N;
cin >> N;
hanoi(N, 'A', 'B', 'C');
return 0;
}