详解汉诺塔

题目《20级计科ACM程序设计》–递归与递推 - Virtual Judge (sdtbu.edu.cn)

思路

  • 汉诺塔问题:

  • 如果n==1,A->C

  • 如果n>1,分三步:

  • 1.将n-1块,借助A移动到B,终点是B

  • 2.将A最底下的那一块移动到C

  • 3.将刚才的n-1借助A移动到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的回答 - 知乎 https://www.zhihu.com/question/24385418/answer/257751077

    对递归的理解的要点主要在于放弃!

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

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

  • #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;
    /*
    
    * 汉诺塔问题:
    * 如果n==1,A->C
    * 如果n>1,分三步:
    * 1.将n-1块,借助A移动到B,终点是B
    * 2.将A最底下的那一块移动到C
    * 3.将刚才的n-1借助A移动到C,终点是C
    * 而在完成第三步时,显然又回到1,2两步
      */
      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;
      }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值