递归思想适用于问题可以被分解成多个子问题的情况。在汉诺塔问题中,每个子问题都可以被看作是一个更小的汉诺塔问题,因此可以使用递归思想进行求解。
可以把此问题分解成三个步骤:
先将 n-1 个棋子从 A 经过 C 移动到 B(借助柱子 C)。
将 A 上剩下的一个棋子直接移动到 C。
最后将 B 上的 n-1 个棋子经过 A 移动到 C(借助柱子 A)。
每次移动时都需要调用一个 move() 函数,用来记录移动次数和打印移动的过程。
当棋子数目为1时,问题已经求解,直接移动即可。
当棋子数目大于1时,问题可以分解成多个子问题,按照递归思路进行求解。
递归求解的边界条件是当棋子数目为1时,直接将其从 A 移动到 C。
以下是代码的详细注释:
#include<iostream>
using namespace std;
int i=0; //定义全局变量i,用于计数
void move(char start,char end) //定义函数move,用于打印移动过程
{
i=i+1; //每调用一次move函数,i自增1
}
void HanNuoTa(int n,char A,char B,char C) //定义函数HanNuoTa,用于递归求解汉诺塔问题
{
if(n==1) //当只有一个棋子时,直接将其从A移动到C
{
move(A,C); //调用move函数,打印移动过程
}
else //当棋子数目不为1时,按照递归思路求解
{
HanNuoTa(n-1,A,C,B); //先将n-1个棋子从A经过C移动到B
move(A,C); //再将最下面的一个棋子从A移动到C
HanNuoTa(n-1,B,A,C); //最后将n-1个棋子从B经过A移动到C
}
}
int main()
{
int m; //定义变量m,用于存储棋子数目
cout<<"输入棋子数目:";
cin>>m; //从控制台输入棋子数目
HanNuoTa(m,'A','B','C'); //调用HanNuoTa函数,求解汉诺塔问题
cout<<"共需要移动"<<i<<"次"; //输出移动次数
return 0;
}