加载中...

【题解】汉诺塔


题目汉诺塔

题意:

题意很简单不再赘述。

思路:

汉诺塔问题:

如果n==1,A->C

如果n>1,分三步:

1.先将前n-1块石板,借助C从A移动到B,终点是B

2.将第n块石板从A移动到C

3.将刚才放到B上的n-1块石板借助A从B移动到C,终点是C

而在完成第三步时,显然又回到1,2两步

那么,问题的关键就在于,为什么形参要这样写,先a c b 后b a c ,依据是什么?

我们先看第一步,我们要借助C将n-1块石板从A移动到B,显然我们的终点是B,那么将起点A放到开始,将B放到尾部。

第二步,直接输出即可。

第三步,借助A从B移动到C,起点是B,终点是C,这样写也没有问题。

那么,依据是什么呢?很遗憾,无法给出递归之间一层层清晰的解释,但在翻看各种解释之后,我觉得有个博主说的很有道理:如何理解汉诺塔的递归? - Fireman A的回答 - 知乎

1.对递归的理解的要点主要在于放弃! 放弃你对于理解和跟踪递归全程的企图,只理解递归两层之间的交接,以及递归终结的条件。

2.放弃的基础在于信任,信任数学归纳法。

ps:

刚学习完循环开始接触递归时的我:“递归是魔法!”

代码:


#include<map>
#include<queue>
#include<cmath>
#include<string>//使用to_string必须加该头文件
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long 
#define itn int
const int array_size = (int)1e6 + 50;
const int INF = 0x3f3f3f3f;
using namespace std;

void slove(int n,char a,char b,char c)
{
    if (n == 1)cout <<"Move disk "<<1<<" from " << a << " to " << c << endl;
    else
    {
        slove(n - 1, a, c, b);
        cout << "Move disk " << n << " from " << a << " to " << c << endl;
        slove(n - 1, b, a, c);
    }
}
int main()
{
    int n;
    cin >> n;
    slove(n,'A','B','C');
    return 0;
}

文章作者: 心意
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 心意 !
评论
  目录