【问题描述】
传说在印度的一个神庙前有三根金刚石柱 A,B,C,在 A 石柱上串有 64 个大小各异的圆形金盘,这些圆盘按照大小排列整齐,最大的圆盘在最下方,最小的圆盘在最上方。伟大的勃拉玛神允许人们按照如下这些规则移动圆盘:
1、圆盘只能在三根柱子间移动;
2、一次只能移动一个位于某柱柱顶的圆盘;
3、任何时候不允许将大盘压在小盘上面。
勃拉玛神告诉僧众,如果有人将圆盘从 A 柱移动到 C 柱,世界就将毁灭。这就是著名的汉诺塔(Hanoi)问题。
【输入格式】
仅一行,包含一个正整数N(N<=10),表示初始状态下A柱上的圆盘数。
【输出格式】
共若干行,每行表示一次移动操作,包含用“->”隔开的两个大小写字母,表示将编号为第一个大写字母的石柱顶端的圆盘移动到编号为第二个大写字母的石柱顶端。
【输入样例】
3
【输出样例】
A->C
A->B
C->B
A->C
B->A
B->C
A->C
【数据范围】
N<=10
复习中偶然点开递归,看了看汉诺塔,不得不说的确是经典中的经典,因此写下第二次看本题的感想与思路。递归其实就是递推的一个逆过程,由边界层层推进。汉诺塔也是如此,无论如何移动,它总会等到n=1或n=0的时候。
本题的思路在于要将n-1个盘子看成一个整体,从初始状态开始会发现,n-1会到B这个中转站,而最大的那个则到C,所以是先移到B,再移到C
而此时又会发现该状态时又会以B为起点,以A为中转站将最大的移到C的操作。
因此我们总结出该递归有两种状态,且有顺序关系,所以设出两种递归式
代码尤其简单,粘上多年前的代码
#include<cstdio>
#include<iostream>
using namespace std;
void k(int n,char A,char B,char C)
{ if (n==0) return;
k(n-1,A,C,B);
printf("%c->%c\n",A,C);
k(n-1,B,A,C);
}
int main()
{ int n;
scanf("%d",&n);
k(n,'A','B','C');
return 0;
}