《算法设计与分析》递归算法典型例题
- 格式:doc
- 大小:302.00 KB
- 文档页数:7
递归算法及经典例题详解
1.什么是递归
递归简单来说就是在运行过程中不断调用自己,直到碰到终止条件,返回结果的过程。
递归可以看作两个过程,分别是递和归。
递就是原问题把要计算的结果传给子问题;归则是子问题求出结果后,把结果层层返回原问题的过程。
下面设一个需要经过三次递归的问题,为大家详细看一下递归的过程:当然,现实中我们遇到递归问题是不会按照图中一样一步一步想下来,主要还是要掌握递归的思想,找到每个问题中的规律。
2.什么时候使用递归
递归算法无外乎就是以下三点:1.大问题可以拆分为若干小问题2.原问题与子问题除数据规模不同,求解思路完全相同3.存在递归终止条件
而在实际面对递归问题时,我们还需要考虑第四点:
当不满足终止条件时,要如何缩小函数值并让其进入
下一层循环中
3.递归的实际运用(阶层计算)
了解了大概的思路,现在就要开始实战了。
下面我们来看一道经典例题:
求N的阶层。
首先按照思路分析是否可以使用递归算法:
1.N!可以拆分为(N-1)!*N
2.(N-1)!与N!只有数字规模不同,求解思路相同
3.当N=1时,结果为1,递归终止
满足条件,可以递归:
publicstaticintFactorial(int num){if(num==1){return num;}return num*Factorial(num-1);}
而最后的return,便是第四步,缩小参数num的值,让递归进入下一层。
一般来说,第四步往往是最难的,需要弄清该如何缩
小范围,如何操作返回的数值,这一步只能通过不断
地练习提高了(当然如果你知道问题的数学规律也是
可以试出来的)。
1、实验内容递归求n的二次方各项的系数。
2、程序设计代码如下:#include"stdio.h"void coeff(int a[],int n)if(n==1)a[1]=1;a[2]=1;elsecoeff(a,n-1);a[n+1]=1;for(int i=n;i>=2;i=i-1)a[i]=a[i]+a[i-1];a[1]=1;void main()int a[100],i,n;printf("输入n的值:");scanf("%d",&n);coeff(a,n);for(i=1;i<=n+1;i++)printf(" %d ",a[i]);printf("\n");1、实验内容写出计算ackerman函数ack(m,n)的递归计算函数。
2、程序设计代码如下:#include "stdio.h"int ack(int m,int n)if(m==0)return n+1;else if(n==0)return ack(m-1,1);elsereturn ack(m-1,ack(m,m-1));void main()int m,n,z;printf("input m and n:");scanf("%d %d",&m,&n);if(m<0 && n<0)printf("error input!");elsez=ack(m,n);printf("%d\n",z);第四章例15 求数列的最大子段和给定n个元素的整数列(可能为负整数)a1,a2,…..,an。
求形如:ai,ai+1,……aj i,j=1,…..,n,i<=j的子段,使其和为最大。
以下是递归时间复杂度的例子:
1.计算整数x的n次方
暴力算法的时间复杂度为O(n),空间复杂度为O(1)。
而使用递归算法,每次递归可以将问题规模减半,因此时间复杂度可以降低到O(logn),但空间复杂度会增加到O(logn)。
2.斐波那契数列
斐波那契数列是一个经典的递归问题,其定义如下:F(0) = 0,F(1) = 1,F(n) = F(n-1) + F(n-2)(n >= 2)。
如果直接使用递归算法来计算斐波那契数列的第n项,时间复杂度会达到O(2^n),因为会有很多重复的计算。
可以使用动态规划或记忆化搜索来优化算法,将时间复杂度降低到O(n)。
3.归并排序
归并排序是一种使用递归的排序算法,其基本思想是将待排序的数组分成两半,分别递归地对它们进行排序,然后将排好序的两个子数组合并成一个有序的数组。
归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。
4.汉诺塔问题
汉诺塔问题是一个经典的递归问题,其目标是将一堆大小不同的盘子从一个柱子移动到另一个柱子上,并满足以下条件:每次只能移动一个盘子;大盘子不能放在小盘子上面。
可以使用递归算法来解决汉诺塔问题,其基本思想是将问题分解成两个子问题:将上面的n-1个盘子从起始柱子移动到辅助柱子上,再将最大的盘子从起始柱子移动到目标柱子上,最后将n-1个盘子从辅助柱子移动到目标柱子上。
汉诺塔问题的时间复杂度为O(2^n),空间复杂度为O(n)。
这些例子表明,递归算法的时间复杂度和空间复杂度取决于问题的性质和递归的实现方式。
因此,在设计递归算法时,需要仔细分析问题,选择合适的递归策略,并进行适当的优化。
算法递归典型例题实验一:递归策略运用练习三、实验项目1.运用递归策略设计算法实现下述题目的求解过程。
题目列表如下:(1)运动会开了N天,一共发出金牌M枚。
第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。
到了第N天刚好还有金牌N枚,到此金牌全部发完。
编程求N和M。
(2)国王分财产。
某国王临终前给儿子们分财产。
他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i 个儿子i份,再加上剩余财产的1/10。
每个儿子都窃窃自喜。
以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。
请用程序回答,老国王共有几个儿子?财产共分成了多少份?源程序:(3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。
问这鱼缸里原有多少条金鱼?(4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少?(5)猴子吃桃。
有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子?(6)小华读书。
第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页?(7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。
算法分析与设计(答案)一:二分查找的递归实现算法import java.util.Arrays;import java.util.Scanner;public class BinSearch {public static int binsearch(int[]a,int start,int stop,int b){if(start>stop)return -1;int i=(start+stop)/2;if(a[i]==b)return i;if(a[i]>b)return binsearch(a,start,i-1,b);return binsearch(a,i+1,stop,b);}/***@param args*/public static void main(String[] args) {// TODO Auto-generated method stubScanner sc=new Scanner(System.in);int n=sc.nextInt();int a[]=new int [n];System.out.println("输入数组元素");for(int i=0;i<n;i++){a[i]=sc.nextInt();}Arrays.sort(a);System.out.println("排序后的数组为");for(int i=0;i<a.length;i++){System.out.print(a[i]+" ");}System.out.println();System.out.println("输入要查找的数");int b=sc.nextInt();int x=binsearch(a,0,n-1,b);if(x==-1){System.out.println(b+"不在数组中,请输入另一个数");b=sc.nextInt();x=binsearch(a,0,n-1,b);}System.out.println(b+"在数组中的第"+(x+1)+"个位置");}}二:Ackerman函数的递归实现算法import java.util.Scanner;public class Test2 {private static int akm(int n, int m) {// 递归设计int r, g;if (n == 1 && m == 0)r = 2;else if (n == 0 && m >= 0)r = 1;else if (m == 1)r = n * 2;else if (m == 2)r = (int) Math.pow(2, n);else if (m == 0 && n >= 2)r = n + 2;else {g = akm(n-1, m);r = akm(g, m-1);// 两次连着递归}return r;}public static void main(String[] args) {try {System.out.println("请输入1个大于等于0的整数:");Scanner sc = new Scanner(System.in);int n = sc.nextInt();System.out.println("请再输入1个大于等于0的整数:");int m = sc.nextInt();System.out.println(akm(n, m));} catch (Exception e) {}}}三:全排列的递归实现算法import java.util.Scanner;public class AllSort{//全排列public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("输入需要全排列的元素个数");int n=(char) sc.nextInt();int buf[]=new int [n];System.out.println("请依次输入每一个元素");for(int i=0;i<n;i++){buf[i]=sc.nextInt();}perm(buf,0,buf.length-1);}public static void perm(int[] buf,int start,int end){ if(start==end){//当只要求对数组中一个元素进行全排列时,只要就按该数组输出即可(特殊情况)for(int i=0;i<=end;i++){System.out.print(buf[i]);}System.out.println();}else{//多个字母全排列(普遍情况)for(int i=start;i<=end;i++){//(让指针start分别指向每一个数)int temp=buf[start];//交换数组第一个元素与后续的元素buf[start]=buf[i];buf[i]=temp;perm(buf,start+1,end);//后续元素递归全排列temp=buf[start];//将交换后的数组还原buf[start]=buf[i];buf[i]=temp;}}}}四:快速排序的递归实现算法import java.util.Scanner;public class QuickSort {public static int []a;public static void quicksort(int p,int r){if(p<r){int q=partition(p,r);quicksort(p,q-1);quicksort(q+1,r);}}public static int partition(int p,int r){int i=p,j=r+1;int x=a[p];while(true){while(a[++i]<x&&i<r);while(a[--j]>x);if(i>=j)break;int temp=a[i];a[i]=a[j];a[j]=temp;}a[p]=a[j];a[j]=x;return j;}/***@param args*/public static void main(String[] args) {// TODO Auto-generated method stubScanner sc=new Scanner(System.in);System.out.println("输入要排序的数组长度");int n=sc.nextInt();a=new int[n];System.out.println("输入"+n+"个元素");for(int i=0;i<n;i++)a[i]=sc.nextInt();quicksort(0,n-1);System.out.println("排序后的数组为");for(int j=0;j<a.length;j++)System.out.print(a[j]+" ");}}五:整数划分的递归实现算法import java.io.IOException;import java.util.*;public class ZhengshuHuafen {public static int a=0 ;public static int Devide(int input, int base, int []pData, int index){if(input<1||base<1)return 0;if(input==1||base==1){if(input==1){pData[index] = input;print(pData, index+1);}else{for(int k=0; k<input; k++){pData[index++] = base;}print(pData,index);}return 1;}if(input==base){pData[index] = base;print(pData,index+1);int temp = Devide(input,base-1,pData,index);return 1 + temp;}if(input<base){int temp = Devide(input,input,pData,index);return temp;}else{pData[index] = base;int temp1 = Devide(input-base,base,pData,index+1); int temp2 = Devide(input,base-1,pData,index);return temp1 + temp2;}}public static void print(int []pData ,int index){String s = new String();for(int i = 0 ; i < index - 1 ; i++){System.out.print(pData[i]+"+");s += String.valueOf(pData[i]);s += "+"; }System.out.println(pData[index-1]);s += String.valueOf(pData[index-1]) +"\r\n";}public static void main(String[] args) {int n ;Scanner in = new Scanner(System.in) ;System.out.print("请输入一个整数") ;n = in.nextInt() ;System.out.println("你刚才输入的数为"+n) ;int []pdata = new int[n] ;a=Devide(n, n, pdata, 0) ;System.out.println(""+a) ;}}六:合并排序的递归实现算法import java.util.Scanner;public class mergeSort {public static int []b;public static void mergeSort1(int []a,int left,int right) {if(left<right){int i=(left+right)/2;mergeSort1(a,left,i);mergeSort1(a,i+1,right);merge(a,b,left,i,right);copy(a,b,left,right);}}public static void merge(int []c,int []d,int l,int m,int r) {int i=l;int j=m+1;int k=l;while((i<=m)&&(j<=r))if(c[i]<=c[j])d[k++]=c[i++];else d[k++]=c[j++];if(i>m)for(int q=j;q<=r;q++)d[k++]=c[q];elsefor(int q=i;q<=m;q++)d[k++]=c[q];}public static void copy (int[]c,int[]b,int left,int right) {for(int i=left;i<=right;i++){c[i]=b[i];}}public static void main(String[]args){Scanner sc=new Scanner(System.in);int n=sc.nextInt();b=new int[n];int []a;a=new int [n];for(int i=0;i<n;i++){a[i]=sc.nextInt();}mergeSort.mergeSort1(a,0,n-1);for(int j=0;j<=n-1;j++)System.out.print(a[j]+" ");}}。
算法递归典型例题实验一:递归策略运用练习三、实验项目1.运用递归策略设计算法实现下述题目的求解过程。
题目列表如下:(1)运动会开了N天,一共发出金牌M枚。
第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。
到了第N天刚好还有金牌N枚,到此金牌全部发完。
编程求N和M。
(2)国王分财产。
某国王临终前给儿子们分财产。
他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i个儿子i份,再加上剩余财产的1/10。
每个儿子都窃窃自喜。
以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。
请用程序回答,老国王共有几个儿子?财产共分成了多少份?源程序:(3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。
问这鱼缸里原有多少条金鱼?(4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少?(5)猴子吃桃。
有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子?(6)小华读书。
第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页?(7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。
【关键字】分析《算法分析与设计》作业参考答案作业一一、名词解释:1.递归算法:直接或间接地调用自身的算法称为递归算法。
2.程序:程序是算法用某种程序设计语言的具体实现。
2、简答题:1.算法需要满足哪些性质?简述之。
算法是若干指令的有穷序列,满足性质:1)输入:有零个或多个外部量作为算法的输入。
2)输出:算法产生至少一个量作为输出。
3)确定性:组成算法的每条指令清晰、无歧义。
4)有限性:算法中每条指令的执行次数有限,执行每条指令的时间也有限。
2.简要分析分治法能解决的问题具有的特征。
分析分治法能解决的问题主要具有如下特征:1)该问题的规模缩小到一定的程度就可以容易地解决;2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;3)利用该问题分解出的子问题的解可以合并为该问题的解;4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
3.简要分析在递归算法中消除递归调用,将递归算法转化为非递归算法的方法。
将递归算法转化为非递归算法的方法主要有:1)采用一个用户定义的栈来模拟系统的递归调用工作栈。
该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
2)用递推来实现递归函数。
3)通过Cooper变换、反演变换能将一些递归转化为尾递归,从而迭代求出结果。
后两种方法在时空复杂度上均有较大改善,但其适用范围有限。
三、算法编写及算法应用分析题:1.冒泡排序算法的基本运算如下:for i ←1 to n-1 dofor j ←1 to n-i doif a[j]<a[j+1] then交换a[j]、a[j+1];分析该算法的时间复杂性。
解答:排序算法的基本运算步为元素比较,冒泡排序算法的时间复杂性就是求比较次数与n的关系。
1)设比较一次花时间1;2)内循环次数为:n-i次,(i=1,…n),花时间为:3)外循环次数为:n-1,花时间为:2.设计一个分治算法计算一棵二叉树的高度。
算法递归典型例题实验一:递归策略运用练习三、实验项目1运用递归策略设计算法实现下述题目的求解过程。
题目列表如下:(1)运动会开了N天,一共发岀金牌M枚。
第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。
到了第N天刚好还有金牌N枚,到此金牌全部发完。
编程求(2)国王分财产。
某国王临终前给儿子们分财产。
他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10 ;……;给第i个儿子i份,再加上剩余财产的1/10。
每个儿子都窃窃自喜。
以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。
请用程序回答,老国王共有几个儿子?财产共分成了多少份?源程序:(3)岀售金鱼问题:第一次卖岀全部金鱼的一半加二分之一条金鱼;第二次卖岀乘余金鱼的三分之一加三分之一条金鱼;第三次卖岀剩余金鱼的四分之一加四分之一条金鱼;第四次卖岀剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在岀售金鱼时不能把金鱼切开或者有任何破损的。
问这鱼缸里原有多少条金鱼?(4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少?(5)猴子吃桃。
有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推) ,第九天正好吃完,问猴子们摘来了多少桃子?(6)小华读书。
第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页?(7)日本著名数学游戏专家中村义作教授提岀这样一个问题:父亲将2520个桔子分给六个儿子。
分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7 给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。
算法递归典型例题实验一:递归策略运用练习三、实验项目1.运用递归策略设计算法实现下述题目的求解过程。
题目列表如下:(1)运动会开了N天,一共发出金牌M枚。
第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。
到了第N天刚好还有金牌N枚,到此金牌全部发完。
编程求N和M。
(2)国王分财产。
某国王临终前给儿子们分财产。
他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i 个儿子i份,再加上剩余财产的1/10。
每个儿子都窃窃自喜。
以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。
请用程序回答,老国王共有几个儿子?财产共分成了多少份?源程序:(3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。
问这鱼缸里原有多少条金鱼?(4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少?(5)猴子吃桃。
有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子?(6)小华读书。
第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页?(7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。
分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。
结果大家手中的桔子正好一样多。
问六兄弟原来手中各有多少桔子?四、实验过程(一)题目一:……1.题目分析由已知可得,运动会最后一天剩余的金牌数gold等于运动会举行的天数由此可倒推每一天的金牌剩余数,且每天的金牌数应为6的倍数。
2.算法构造设运动会举行了N天,If(i==N)Gold[i]=N;Else gold[i]=gold[i+1]*7/6+i;3.算法实现#include <iostream> // 预编译命令using namespace std;void main() //主函数{int i=0,count=0; //count表示运动会举办的天数int gold[100]; //定义储存数组do{count=count+6; // 运动会天数加六gold[count]=count;for (i=count-1; i>=1; i--){if (gold[i+1]%6!=0 )break; // 跳出for循环elsegold[i]=gold[i+1]*7/6+i; //计算第i天剩余的金牌数}} while( i>=1 ); // 当i>=1 继续做do循环cout <<"运动会开了"<<count<<"天"<< endl; //返回天数cout<<"总共发了"<<gold[1]<<"枚金牌"<<endl; //返回金牌数}4.运行结果(二)题目二:……1.题目分析由已知可得,最后一个儿子得到的遗产份数即为王子数目,由此可得到每个儿子得到的遗产份数,在对遗产数目进行合理性判断可得到符合要求的结果。
2.算法构造设皇帝有count个王子,property[count]=count;for (i=count-1; i>=1; i--){if (property[i+1]%9!=0 )break; // 数目不符跳出for循环elseproperty[i]=property[i+1]*10/9+i; //计算到第i个王子时剩余份数}3.算法实现#include <iostream> // 预编译命令using namespace std;void main() //主函数{int i=0,count=0; //count表示国王的儿子数int property[100]; //定义储存数组,表示分配到每个王子时剩余份数do{count=count+9; //王子数目为9的倍数property[count]=count;for (i=count-1; i>=1; i--){if (property[i+1]%9!=0 )break; // 数目不符跳出for循环elseproperty[i]=property[i+1]*10/9+i; //计算到第i个王子时剩余份数}} while( i>=1 ); // 当i>=1 继续做do循环cout <<"皇帝有"<<count<<"个儿子"<< endl; //返回王子数cout<<"遗产被分成"<<property[1]<<"份"<<endl; //返回遗产份数}4.运行结果(三)题目三:……1.题目分析由最后一天的金鱼数目,可递推得到每天的金鱼数目,第一天的数目即为金鱼总数。
2.算法构造fish[5]=11;for (i=4; i>=1; i--)fish[i]=(fish[i+1]*(i+1)+1)/i; //计算到第i天剩余金鱼条数3.算法实现#include <iostream> // 预编译命令using namespace std;void main() //主函数{int i=0;int fish[6]; //定义储存数组各天剩余金鱼数fish[5]=11;for (i=4; i>=1; i--)fish[i]=(fish[i+1]*(i+1)+1)/i; //计算到第i天剩余金鱼条数c out<<"浴缸里原有金鱼"<<fish[1]<<"条"<<endl; //返总金鱼数}4.运行结果(四)题目四:……1.题目分析有到终点站时车上的乘客数可求得到任意一站的乘客人数,到第二站时车上的乘客数目即为发车时车上的乘客数。
2.算法构造n um[8]=6; //到终点站车上还有六人f or(i=7; i>=2; i--)num[i]=2*(num[i+1]-8+i); //计算到第i站车上的人数3.算法实现#include <iostream> // 预编译命令using namespace std;void main() //主函数{int i=0;i nt num[9]; //定义储存数组n um[8]=6; //到终点站车上还有六人f or(i=7; i>=2; i--)num[i]=2*(num[i+1]-8+i); //计算到第i站车上的人数c out<<"发车时车上有"<<num[2]<<"位乘客"<<endl; //返总发站人数,即为到第二站时车上人数}4.运行结果(五)题目五:……1.题目分析可假设有第十天,则第十天剩余的桃子数目为0,由此递推可得每一天剩余的桃子数目。
第一天的桃子数目即为猴子摘桃子的总数。
2.算法构造n um[10]=0; //第n天吃前的桃子数f or(i=9; i>=1; i--)3.算法实现num[i]=2*(num[i+1]+1); //计算到第i天剩余的桃子数算法实现#include <iostream> // 预编译命令using namespace std;void main() //主函数{int i=0;i nt num[11]; //定义储存数组n um[10]=0; //第n天吃前的桃子数f or(i=9; i>=1; i--)num[i]=2*(num[i+1]+1); //计算到第i天剩余的桃子数c out<<"猴子共摘来了"<<num[1]<<"个桃子"<<endl; //输出总的桃子数,即第一天吃前的数目}4.运行结果(六)题目六:……1.题目分析由第六天剩余的页数可递推得到每天的剩余页数,第一天的页数即为全书的页数2.算法构造num[6]=3; //到第n天时剩余的页数f or(i=5; i>=1; i--)num[i]=2*(num[i+1]+2); //计算到第i天剩余的页数3.算法实现#include <iostream> // 预编译命令using namespace std;void main() //主函数{int i=0;i nt num[7]; //定义储存数组n um[6]=3; //到第n天时剩余的页数f or(i=5; i>=1; i--)num[i]=2*(num[i+1]+2); //计算到第i天剩余的页数c out<<"全书共有"<<num[1]<<"页"<<endl; //输出总页数,即第一天吃前的数目}4.运行结果(七)题目七:……1.题目分析由已知可得,第一个儿子得到的橘子数目为平均数的一半,由此可得到第一个儿子原先的橘子数目,而第i个儿子原先的橘子数目可由递推公式得到;2.算法构造if(i==0){a[i]=(ave-ave/2)*(8-i)/(8-i-1); //第一个儿子的数目left=a[i]-ave/2;}else{a[i]=ave*(8-i)/(8-i-1)-left; //由left求第i+1个儿子的橘子数目left=ave/(8-i-1); //第i+1个儿子得到的橘子数目}3.算法实现#include<iostream>using namespace std;void main(){i nt a[6]; //存放六个儿子原先手中的橘子数目i nt left=0; //存放下一个儿子得到的橘子数目i nt ave=420;f or(int i=0;i<6;i++){if(i==0){a[i]=(ave-ave/2)*(8-i)/(8-i-1); //第一个儿子的数目left=a[i]-ave/2;}else{a[i]=ave*(8-i)/(8-i-1)-left; //由left求第i+1个儿子的橘子数目left=ave/(8-i-1); //第i+1个儿子得到的橘子数目}}f or(i=0;i<6;i++)cout<<"第"<<i+1<<"个儿子原先手中的的橘子数为"<<a[i]<<endl; //输出每个儿子原先手中的橘子数目}4.运行结果。