汉诺塔问题
从大一开始做汉诺塔问题,当时没弄明白就放那了,最近又认真看了看,好不容易觉得自己弄明白了。
说明一点:递归注重的是思想,不要试图去完整的理解整个的执行过程,只要整体对了,这个递归就是正确的。
引用别人的一句话:对递归的理解的要点在于放弃,放弃对于理解和跟踪递归全程的企图,只理解递归两层之间的交接,以及递归终结的条件。
递归的产生就是为了将复杂问题分解成一个个的子问题进行解决,不要再去模拟整个过程,将问题复杂化。
下面说一下我对汉诺塔的理解:
a是源轴,b是辅助轴,c是目标轴
首先将a上面的n-1个盘子看成一个整体,移动到b上面去,再把a上面的最后一个盘子移动到c上面去。这时候b上面有很多的盘子,把b看作a即源轴,把a看作b即辅助轴,c还是目标轴,就变成了跟第一次移动的一样的问题。
#include<bits/stdc++.h>
#include <stdio.h>
using namespace std;
void move(char x,char y)
{
printf("Move %c->%c\n",x,y);//每移动一次就打印
}
//n为盘子总个数,其他参数为a上的盘子借助于b移动到c上面去即a为源轴,b为辅助轴,c为目标轴
long long HanTowel(int n,char a,char b,char c)
{
static long long count=0;
count++;//移动次数
if(n==1)//直接从源轴移动到目标轴
move(a,c);
else
{
//以下为一个递归过程,子问题
HanTowel(n-1,a,c,b);//注意:a不一定代表x轴,只是一个参数
//将n-1个盘子从a移动到b上面以后,将a上面的最后一个盘子移动到目标轴上
move(a,c);
//再把b上的盘子看作一个盘子,移动到目标轴上,此时b上面有很多盘子作为源轴,a轴上面为空作为辅助轴,c一直是目标轴
HanTowel(n-1,b,a,c);
}
return count;//返回移动次数
}
int main()
{
int n;
cin>>n;
long long ret=HanTowel(n,'A','B','C');
cout<<ret<<endl;
return 0;
}
以下为觉得讲的比较好的,加深理解:
https://www.zhihu.com/question/24385418
https://www.cnblogs.com/tgycoder/p/6063722.html(里面有动画,可以帮助理解)