千家信息网

C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇文章主要介绍"C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现",在日常操作中,相信很多人在C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希
千家信息网最后更新 2025年02月02日C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现

这篇文章主要介绍"C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现",在日常操作中,相信很多人在C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

目录
  • 一、青蛙跳台阶

    • 题目

    • 思路

    • 分析

      • 1. 从跳法次数分析

      • 2. 从过程分析

  • 二、青蛙跳台阶变式1

    • 题目

      • 分析

      • 三、青蛙跳台阶变式2

        • 题目

          • 分析

          • 四、汉诺塔问题(求步数)

            • 题目

              • 思路

                • 分析

                • 五、汉诺塔问题(求移动过程)

                  • 题目

                    • 思路

                      • 分析

                      一、青蛙跳台阶

                      题目

                      一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法

                      思路

                      遇见题目我们可以在纸上先动手画画,把最简单的几种方式列出来,作比较,找规律。


                      分析

                      按照上面表格可以从跳法次数,过程,或者两者结合找规律

                      1. 从跳法次数分析
                      • 观察表格,可以知道从n>=3时,第n个数就是前两个数的和(与斐波那契数列一样)

                      • 我们自己推论,当台阶数为n时,设跳法有f(n)次,如果青蛙先跳1阶,则剩下的台阶数为n-1,即剩余跳法有f(n-1)次;如果青蛙先跳2阶,则剩下的台阶数为n-2,即剩余跳法有f(n-2)次。

                      • 故跳法次数f(n)=f(n-1)+f(n-2),因为等号右边有两个值,故当n=1,n=2时为最后的特殊限制条件

                      • 下面代码为递归求法,如果想用非递归,可以将递归通项改成循环

                      代码1(递归)

                      #include int jump(int n){ if (n == 1)  return 1; if (n == 2)  return 2; return jump(n - 1) + jump(n - 2);}int main(){ int n; scanf("%d", &n); int ret = jump(n); printf("%d", ret); return 0;}
                      2. 从过程分析
                      • 观察表格,可以知道,跳n阶台阶,跳两阶台阶次数可以为0到n/2次,而每一次跳两阶台阶的顺序也是不定的。可以通过计数原理的组合数C(n,m),表示从n个数中选m个数排列。n表示每次需要跳的次数,m表示一次跳两阶的次数

                      • 组合数C(n,m),可以由n!/(m!*(n-m)!)求得

                      • 下面代码为非递归求法,如果想要写成递归,可以根据循环修改

                      代码2(非递归)

                      #include int fac(int m){ int i = 0; int count = 1; for (i = 1; i <= m; i++) {  count *= i; } return count;}int jump(int n){ int i = 0;      //i为跳两阶台阶的次数 int sum = 0;     //sum为计算跳法 for (i = 0; i <= n / 2; i++) {  int a = 0;  a = n - i * 2 + i;   //a为跳到n阶台阶跳的次数   sum += fac(a) / (fac(i)*fac(a - i)); } return sum;}int main(){ int n; scanf("%d", &n); int ret = jump(n); printf("%d", ret); return 0;}

                      二、青蛙跳台阶变式1

                      题目

                      一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶…也可以跳n级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法

                      分析

                      • 根据原题推论,当台阶数为n时,设跳法有f(n)次,如果青蛙先跳1阶,则剩下的台阶数为n-1,即剩余跳法有f(n-1)次;如果青蛙先跳2阶,则剩下的台阶数为n-2,即剩余跳法有f(n-2)次。

                      • 那么当青蛙跳3阶台阶,则剩下的台阶数为n-3,即剩余跳法有f(n-3)次…当青蛙跳n阶台阶,则剩下的台阶数为n-n,即剩余跳法有f(n-n)次

                      • 故跳法次数f(n)=f(n-1)+f(n-2)+f(n-3)…+f(n-n)

                      • 由推论可得f(n-1)=f(n-2)+f(n-3)…+f(n-n),将其代入上面式子

                      • 故跳法次数为f(n)=2*f(n-1),因为等号右边只有一个值,故n=1为最后的特殊限制条件

                      代码3(递归)

                      #include int jump(int n){ if (n == 1)  return 1; return 2*jump(n - 1);}int main(){ int n; scanf("%d", &n); int ret = jump(n); printf("%d", ret); return 0;}

                      三、青蛙跳台阶变式2

                      题目

                      一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶…也可以跳m级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(m<=n)

                      分析

                      • 根据变式1推论得f(n)=f(n-1)+f(n-2)+f(n-3)…+f(n-n)

                      • 而这里最多一次只能跳m阶,故f(n)=f(n-1)+f(n-2)+f(n-3)…+f(n-m)

                      • 由推论得f(n-1)=f(n-2)+f(n-3)…+f(n-m)+f(n-m-1),代入上面式子

                      • 故跳法次数为f(n)=2*f(n-1)-f(n-m-1)

                      • 因为通过递归n的值在减少,当n

                      代码4(递归)

                      #include int jump(int n,int m){ if (n > m)  return 2 * jump(n - 1, m) - jump(n - 1 - m, m); else {  if (n == 1)   return 1;  return 2 * jump(n - 1, n); }}int main(){ int n, m; scanf("%d%d", &n, &m); int ret = jump(n,m); printf("%d", ret); return 0;}

                      四、汉诺塔问题(求步数)

                      题目

                      有A,B,C三个柱子,A柱子上从上到下,从小到大排列着n个圆盘。现要求将A柱子上的n个圆盘全部移动到C柱子上,依然按照从上到下,从小到大的顺序排列。且对移动过程要求如下:

                      a)一次只能移动一个盘子。

                      b)移动过程中大盘子不允许出现在小盘子上方。

                      问:总共需要移动的步数是多少?

                      思路

                      因为求的是步数,我们可以通过找前面几组数据,观察是否有什么规律

                      分析

                      • 通过表格观察,可以知道盘子数为n时,步数为20+21+…+2n-1,即2n-1

                      • 我们可以通过下面这张图片来推论:

                      • 假设盘子数量为n,通过化繁为简思想,我们可以把盘子分成两个部分。上面n-1个盘子,和最下面一个盘子。移动步骤如下:

                      1. 将最上面的n-1个盘子移动到B柱上

                      2. 将最下面的盘子移动到C柱上

                      3. 再将B柱上的n-1个盘子移动到C柱上

                      • 问题转化成如何移动最上面n-1个盘子。按照上面的思路解决n-1个盘子移动的问题。

                      • 假设移动n个盘子需要的步数为f(n),则移动n-1个盘子需要f(n-1)步。

                      • 故移动步数为f(n)=f(n-1)+1+f(n-1),即f(n)=2*f(n-1)+1

                      • 通过等比数列变形又可以得到f(n)=2n-1

                      代码5(非递归)

                      #include #include int main(){ int n; scanf("%d", &n); int count =0;    count=(int)pow(2,n)-1; printf("%d", count); return 0;}

                      代码6(递归)

                      #include int tower(int n){ if (n == 1)  return 1; else  return 2 * tower(n - 1) + 1;}int main(){ int n; scanf("%d", &n); int ret=tower(n); printf("%d", ret); return 0;}

                      五、汉诺塔问题(求移动过程)

                      题目

                      有A,B,C三个柱子,A柱子上从上到下,从小到大排列着n个圆盘。现要求将A柱子上的n个圆盘全部移动到C柱子上,依然按照从上到下,从小到大的顺序排列。且对移动过程要求如下:

                      a)一次只能移动一个盘子。

                      b)移动过程中大盘子不允许出现在小盘子上方。

                      问:打印移动的方案 (例如, 移动A柱最上面的圆盘到C柱, 则输出"A -> C")

                      思路

                      因为求的是移动方案,所以我们可以将前几组数据列出来,结合递归化简为繁的思想找共性和非共性


                      分析

                      • 通过观察得到:除了n=1,n>1时,都是先将A柱上面n-1个盘子拿到B柱(粗字体为其过程),再将A柱最下面盘子拿到C柱。此时A柱变成辅助柱,再将B柱上的盘子放到C柱

                      • 故将A柱最下面盘子移到C柱为中间过程

                      • 上一步为将初始柱(A柱)上面n-1个盘子借助辅助柱(C柱)移到目标柱(B柱)【其实可以这里看作单独一个n-1的汉诺塔,将A柱上的盘子移动到B柱】

                      • 下一步为将初始柱(B柱)上面n-1个盘子借助辅助柱(A柱)移到目标柱(C柱)【其实可以这里看作单独一个n-1的汉诺塔,将B柱上的盘子移动到C柱】

                      • 而上一步,中间过程,下一布就是递归的核心思想

                      • 而当n=1时,盘子数只有一个,我们将其直接放到目标柱即可(其为最终的限制条件)

                      • 初始柱,辅助柱,目标柱,其实就是把该步骤的移动过程当作一个单独的汉诺塔问题,需要移动盘子现在所在的位置为初始柱,要将其放到的位置就是目标柱

                      代码7(递归)

                      #include void hanio(int n, char x, char y, char z){ if (n == 1)  printf("%c->%c\n",x,z);  //当盘子只剩一个时,直接打印初始柱移动到目标柱的过程 else {  hanio(n - 1, x, z, y);  //将n-1个盘子从起始柱放到目标柱(第一次A->B,第二次B->A,后面往复)          printf("%c->%c\n", x, z); //打印初始柱移动到目标柱的过程          hanio(n - 1, y, x, z);  //将n-1个盘子从起始柱放到目标柱(第一次B->C,第二次C->B,后面往复) }}int main(){ int n; scanf("%d", &n); hanio(n,'A','B','C'); return 0;}

                      到此,关于"C语言经典案例青蛙跳台阶和汉诺塔问题怎么实现"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

                      台阶 盘子 移动 青蛙 过程 递归 分析 问题 次数 汉诺 题目 代码 目标 柱子 思路 步数 剩余 推论 圆盘 就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 低分女生可以学计算机网络技术 廊坊市委网络安全工作会议 简历已经进入简历数据库中 软件开发出来了就可以申请软著吗 软件数据库设计应该谁写 梦幻西游2020是哪个服务器 新沂市软件开发公司电话 怎样保护国家网络安全 自组服务器机箱 计算机网络技术属于理学还是文科 服务器设备怎么管理 网络安全基础 原版pdf 北京字跳网络技术有限公司估值 软件开发年底了该不该离职 wind数据库是谁开发的 软件开发方向包括哪些专业 组态王读取sql数据库 互联网智慧小区软件开发 湖北省云服务器虚拟主机 如何做好数据库产品测试 折叠纸盒结构设计软件开发 深圳巴阿特网络技术有限公司 数据库使用分区查询的方式 h5提交数据库 网络安全经费预算规定 什么软件开发要去国外 软件开发审核作业指导 新乡市云鼎网络技术有限公司 服务器屏幕显示2033 小米软件开发的年薪
                      0