运用函数递归解决汉诺塔、青蛙跳台问题以及青蛙跳台潜在问题

简介: 运用函数递归解决汉诺塔、青蛙跳台问题以及青蛙跳台潜在问题

一、汉诺塔

汉诺塔又称河内塔,起源于印度,传说大反天创造世界时做了三根金刚石柱,其中一根柱子上落着六十四片黄金圆盘。大反天命令陀螺门将圆盘按大小顺序重新摆放到另一根柱子上,规定每次只能移动一块,并且大圆盘不能放到小圆。

#include<stdio.h>
int count;
void move(char a, char b, char c, int n)
{
  if (n == 1)
  {
    ++count;
    printf("第%d次移动:将现在%c上的第一个圆盘移到%c\n",count,a,c);
  }
  else if (n > 1)
  {
    move(a, c, b, n - 1);//通过c柱子将a柱子上n-1个圆盘移到b
    ++count;
    printf("第%d次移动:将现在%c上的第一个圆盘移到%c\n",count, a, c);
    move(b, a, c, n - 1);//看下文绿色字体解释
  }
}
 
int main()
{
  int n;
  scanf("%d", &n);
  move('a','b','c', n);
  return 0;
 
}

 


现在我们看下图进行解析 经过这样移动便可将n-1个圆盘移动到b上,这个过程通过代码实现便是上面的:

move(a, c, b, n - 1);

然后将a上最后一个圆盘移到。然后得到下图:

这时我们发现a是空的,b是有2个圆盘,c上有一个最大的圆盘因为其不影响任何其他圆盘放在c上所以我们可以假设c没有圆盘,如果我们把a当作b,b当作a是不是就相当于刚开始n为2个圆盘,故此我们在调用一次函数即递归,代码实现便是move(b, a, c, n - 1);至此函数不断递归下去直到

n-1为1时函数结束!!!这便是递归解决汉诺塔问题了!!!

二、青蛙跳台

青蛙跳台阶问题是一个经典的数学问题,其内容为:一只青蛙一次可以跳上一级台阶或两级台阶,问青蛙从第n级台阶跳上第n+1级台阶,总共有多少种跳法。


下面看一下代码实现:

#include<stdio.h>
int dancestep(int n)
{
  if (n == 1)
  {
    return 1;//当只有一层台阶时有一种跳法
  }
  if (n == 2)
  {
    return 2;//当只有2层台阶时有两种跳法
  }
  if (n > 2)   //n大于二时进行递归运算
  {
    return dancestep(n - 1) + dancestep(n - 2);
  }
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int num = dancestep(n);
  printf("%d\n", num);
  return 0;
}

接下来我们进行分析:

假设青蛙从第n级台阶跳上第n+1级台阶的跳法数为f(n),那么当它只跳一级时,就可以从第n-1级台阶跳上第n级台阶,此时跳法数为f(n-1);当它一次跳两级时,就可以从第n-2级台阶跳上第n级台阶,此时跳法数为f(n-2)。

因此,我们可以得到递推公式:f(n)=f(n-1)+f(n-2)。

根据这个递推公式,我们可以依次计算出从第1级台阶到第n级台阶的所有跳法数。例如,当n=3时,有f(3)=f(2)+f(1)=2+1=3种跳法。

需要注意的是,青蛙跳台阶问题还有其他的变种,例如每次只能跳一级或者每次只能跳两级,但是其本质都是相同的,都可以使用递归的方法来解决。

注:递归虽然代码看着简便但n如果稍微大一点时电脑的计算次数的计算量却非常大

至于为什么看下图:


我们假设n=40由此我们看出当函数需要进行的计算量(n-1)^2,故此我们其实也可以用普通循环的方法来解决青蛙跳台阶的问题。下面展示代码:

#include<stdio.h>
int main()
{
  int a=1, b=2,i,n,sum;
  scanf("%d", &n);
  if (n >= 3)
  {
    for (i = 1; i <= n - 2; i++)
    {
      sum = a + b;
      a = b;
      b = sum;
    }
  }
  else
  {
    sum = n;
  }
  printf("%d", sum);
  return 0;
}

这样计算的代码就不会在n较大时使函数的计算量成指数增长了!!!

好了各位今天的博客就结束了!!!

 

目录
相关文章
|
4月前
[NOIP2002]过河卒 标准递归
[NOIP2002]过河卒 标准递归
35 6
|
4月前
|
存储
【洛谷 P2437】蜜蜂路线 题解(递归+记忆化搜索+高精度)
蜜蜂路线问题:蜜蜂从蜂房$m$到$n$($m&lt;n$)按数字递增爬行。给定$m$和$n$,求路线数。示例:$m=1$,$n=14$,输出$377$。100%数据$1\leq m,n\leq1000$。使用斐波那契序列优化,高精度处理大数。代码实现斐波那契存储并动态规划求解。
51 0
|
5月前
|
机器学习/深度学习 算法 测试技术
青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(二)
这篇内容是关于解题策略的,主要介绍了在面对应用题时可以采用的“三板斧”方法:举例、模拟和找规律。通过一个走楼梯的例子详细解释了这三个步骤如何运用。首先,举例将抽象问题具体化,比如走5级台阶有几种方式。其次,通过模拟不同情况,例如思考走每一步的可能,发现递归或循环的模式。最后,通过找规律归纳出一般性的解决方案,这里发现走台阶问题与斐波那契数列相关。文章还提到了一个拓展案例——矩形覆盖问题,同样可以用类似的方法分析。总的来说,文章强调了解题过程中理解和转化问题的重要性,以及通过训练提升这方面能力。
43 0
|
5月前
|
C语言
青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(一)
这篇内容介绍了C语言学习中的经典例题——斐波那契数列,强调了解题思路的重要性。斐波那契数列是一个数列,其中每个数是前两个数的和。文章指出,很多类似题目,如“青蛙跳台阶”,实质上都在考察斐波那契数列的实现。文中提供了斐波那契数列的定义、代码实现和递归与非递归的思路,并鼓励读者从问题中分析出解题模型,而非直接套用已知方法。此外,还提及了一道相关题目“矩形覆盖问题”,以供进一步练习。
41 0
|
5月前
|
C语言
每天一道C语言编程(递归:斐波那契数,母牛的故事)
每天一道C语言编程(递归:斐波那契数,母牛的故事)
27 0
|
5月前
|
机器学习/深度学习 算法 C++
【动态规划】C++算法:403.青蛙过河
【动态规划】C++算法:403.青蛙过河
汉诺塔+小青蛙跳台阶---《递归》
汉诺塔+小青蛙跳台阶---《递归》
洛谷P1135 奇怪的电梯——广搜
洛谷P1135 奇怪的电梯——广搜
96 0
|
C语言
【C】青蛙跳台阶和汉诺塔问题(递归)
【C】青蛙跳台阶和汉诺塔问题(递归)
118 0
【C】青蛙跳台阶和汉诺塔问题(递归)
|
机器学习/深度学习 算法
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题
<<算法很美>>——(六)——回溯算法(下)—N皇后问题