递归分治归并题解

本文通过汉诺塔、八皇后等经典问题,介绍了递归算法的应用。从简单的递归累加到复杂的递推式计算,再到汉诺塔、八皇后问题的解决方法,详细解析了递归算法的设计思路及实现过程。

1.汉诺塔、八皇后、斐波那契数列
A: 递归计算累加和
前三题均为简单递归,找到递归终止条件即可

   #include <cstdio>
   using namespace std;
   int f(int n)
   {
       if (n == 1)
       {
           return n;
       }
       return n + f(n - 1);
   }
   int main()
   {
       int n;
       scanf("%d", &n);
       printf("%d\n", f(n));
       return 0;
   }

B: 计算递推式

   #include <cstdio>
   using namespace std;
   int a, b, n;
   int f(int n)
   {
       if (n == 1)
       {
           return 1;
       }
       return a * f(n - 1) + b;
   }
   int main()
   {
       while (scanf("%d %d %d", &a, &b, &n) != EOF)
       {
           printf("%d\n", f(n));
       }
       return 0;
   }

C: 计算N阶乘

   #include <cstdio>
   using namespace std;
   long long f(int n)
   {
       if (n == 1)
           return 1;
       else
           return f(n - 1) * n;
   }
   int main()
   {
       int n;
       while (scanf("%d", &n) == 1)
       {
           printf("%lld\n", f(n));
       }
       return 0;
   }

D: 红红的汉诺塔
这题既可以用公式直接输出结果,也可以使用递归的方法求解

公式的方法求解
 
  #include <cstdio>
  #include <iostream>
  #include <cmath>
  using namespace std;
  int main()
  {
      int n, x;
      while(cin >> n >> x){
          cout << (long long)pow(2, n) - 1 << ' ' << (long long)pow(2, n - x) << endl;
      }
      return 0;
  }

// 递归的方法求解

  #include <iostream>
  using namespace std;
  int ans1 = 0, ans2 = 0;  // ans1为总移动数,ans2为编号为X的盘子的移动次数
  void hanio(int n, int x)
  {
      if (n == 1){
          ans1++;
          if (x == 1) ans2++;
          return;
      }
      hanio(n - 1, x);
      ans1++;
      if (x == n) ans2++;
      hanio(n - 1, x);
  }
  
  int main()
  {
      int n, x;
      while(cin >> n >> x){
          ans1 = 0;  // 记得清零
          ans2 = 0;
          hanio(n, x);
          cout << ans1 << ' ' << ans2 << endl;
      }
      return 0;
  }

//如果弄懂了八皇后的代码,重点其实在于如何只输出一次

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int row[9];
    int flag = 1;
    void queen(int now)
    {
        if (now == 9 && flag)
        {
            for (int i = 0; i < 9; i++){
                if(i == 0) printf("%d", row[i] + 1);
                else printf(" %d", row[i] + 1);
            }
            printf("\n");
            flag = 0;
            return;
        }
        int i, j;
        for (i = 0; i < 9; i++)
        {
            for (j = 0; j < now; j++)
            {
                if (i == row[j] || abs(now - j) == abs(i - row[j]))
                    break;
            }
            if (j == now)
            {
                row[now] = i;
                queen(now + 1);
            }
        }
    }
    int main()
    {
        queen(0);
        return 0;
    }

F: 爱吃车厘子的丹丹
找到递归终止条件:当天数等于 n 时,返回 m。
递归式为 f(n) = 2 * (f(n-1) + 1)。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    typedef long long LL;
    int n, m, t;
    int f(int a){
        if(a == n){
            return m;
        }
        return 2 * f(a + 1) + 2;
    }
     
    int main()
    {
        while(cin >> n >> m >> t){
            cout << f(1) * t << endl;
        }
        return 0;
    }

G: 红红爬楼
首先明确要求的 f(n) 表示的是走到 n 级台阶的总方案数。而从前一状态到达当前状态有两种走法,一种为上一级,一种为上两级,递归求和即可。

    #include <cstdio>
    #include <iostream>
    using namespace std;
     
    int f(int x){
        if(x == 1){
            return 1;
        }
        else if(x == 2) return 2;
        else return f(x-1) + f(x-2);
    }
     
    int main()
    {
        int n;
        cin >> n;
        cout << f(n) << endl;
        return 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值