汉诺塔
题目描述 Description
(2)每次移动一个圆盘,小盘只能叠在大盘上面。
(3)把所有圆盘从A柱全部移到C柱。
试解出n个圆盘从A柱全部到C柱上的移动次数,并展示n个圆盘的移动过程。
输入描述 Input Description
圆盘个数n
输出描述 Output Description
移动过程和次数k
样例输入 Sample Input
4
样例输出 Sample Output
A-->B A-->C B-->C A-->B C-->A
C-->B A-->B A-->C B-->C B-->A
C-->A B-->C A-->B A-->C B-->C
k=15
[解题思路]
这个是递归的基础题了,首先静下心来,递归的题要有出口,与找到它的规律。
①首先,当只有一个圆盘的时候,直接A->C。
②当有两个圆盘的时候,因为一次只能移动一个,而且大的不能叠在小的上面,所以,A->B,A->C,B->C。
③当有三个圆盘的时候,移动过程如下 A->C,A->B,C->B,A->C, B->A,B->C,A->C。
通过观察上面的规律,可以发现,n等于1的话,直接移动,即递归的出口。
当 n>1 时,A->C的左侧,两个盘子时A->B,三个盘子时,A->C,A->B,C->B。可以发现,共同的目的都是把A柱上的n-1个盘子移动到B,而三个盘子时无法直接移动就需要借助C柱,故Hanoi(n-1,A,C,B),A为开始位置,C为中间转换,B为目的柱子。
同理在A->C的右侧,两个盘子时候B->C,三个盘子,B->A,B->C,A->C。共同的目的都是把B柱上的n-1个盘子移动到C,而三个盘子时需要借助A柱,故Hanoi(n-1,B,A,C),B为开始位置,A为中间转换,C为目的柱子。
[代码实现]
#include<iostream>
using namespace std;
int k=0;
void Move(char a, char c)
{
cout<<a<<"-->"<<c<<" ";
k++; /* 统计次数 */
if( k%5 == 0) /* 输出格式控制。每5个换行 */
{
cout<<endl;
}
}
void Hanoi(int n,const char &a, const char &b, const char &c)
{
if(n == 1)
Move(a,c);
else
{
Hanoi(n-1,a,c,b); /* 左侧,a借助c把(n-1)个盘子转移到b */
Move(a,c);
Hanoi(n-1,b,a,c); /* 右侧,b借助a把(n-1)个盘子转移到c */
}
}
int main()
{
char A='A',B='B',C='C';
int n=0;
cin>>n;
Hanoi(n,A,B,C); /* A柱借助B柱把n个盘子转移到C柱*/
cout<<endl<<"k="<<k<<endl;
}