用递归如下

1.一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?

(1)题目分析:

经过7个村子后还剩下两只鸭子,每经过一个村庄卖当前鸭子的一半加一只,所以递归出口为经过第七个村子剩下的两只,递归体为经过下一个村子的鸭子数加1乘以2就是当前村子的鸭子数。
(2)算法构造:

 total(number)=2;  number=7
 total(number)=(total(number+1)+1)*2   0<number<7  

代码实现如下:

/*
Author:王连霞
date:2018-11-15
version:1.0
desciption:通过递归实现一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
*/
#include <iostream>
using namespace std;
int x;
int total(int number)      //递归函数,number表示经过的村子数
{
    if(number==7)       //递归出口,当经过第七个村子后,剩下两只鸭子
    {
       return 2;
    }
    else {
       return (total(number+1)+1)*2;   //递归体,鸭子总数为经过后一天鸭子数+1乘以2
    }
}
/*主函数*/
void main()
{   cout<<"他总共赶了"<<total(0)<<"只鸭子"<<endl;
    for(int i=7;i>0;i--)
    {
    cout<<"他经过第"<<i<<"个村子卖出"<<(total(i-1)/2+1)<<"只鸭子"<<endl;
    }
}

运行结果:
在这里插入图片描述
2.

2.角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。

如:输入22,

输出 22 11 34 17 52 26 13 40 20
10 5 16 8 4 2 1

STEP=16

(1) 题目分析:设fun(n)表示关于自然数n的一个函数,由题意已知,当n=1时,fun(1)=1。当n>1且n为偶数时,fun(n)=fun(n/2);当
n>1且n为奇数时,fun(n)=fun(3*n+1)。得到自然数1的运算次数为每次运算次数之和。

(2) 算法构造:

  fun(n)=1   ,n=1
  fun(n)=fun(n/2)   ,n>1且n为偶数
  fun(n)=fun(3*n+1) ,n>1且n为奇数

(3) 代码实现:



/*

Author:王连霞

date:2018-11-15

version:1.0

desciption:通过递归实现 角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1。*/

#include <iostream>
using  namespace std;
int  function(int *step,int n)   //递归函数,step表示步数,n表示输入的数
{
    if(n==1)             //递归出口,当n为1时结束递归调用 
    {
       return 1;
    }
    if(n%2==0)             //递归体,当n为偶数时将其除以2
    {
       cout<<n<<endl;
       (*step)++;
       return function(step,n/2);
    }
    else if(n%2!=0)          //递归体,当n为奇数时将其乘以3加1
    {
       cout<<n<<endl;
       (*step)++;
       return function(step,n*3+1);
    }
}
void  main()
{
    int n;
    int step=1;         
    cout<<"请输入你的数字:"<<endl;
    cin>>n;
    function(&step,n);       //调用递归函数
    cout<<"总的步数为"<<step<<endl;
}

(4)运行结果:
在这里插入图片描述
3.

3.电话号码对应的字符组合:在电话或者手机上,一个数字如2对应着字母ABC,7对应着PQRS。那么数字串27所对应的字符的可能组合就有3*4=12种(如AP,BR等)。现在输入一个3到11位长的电话号码,请打印出这个电话号码所对应的字符的所有可能组合和组合数。

(1)题目分析
1,0——1""
2——3"ABC"
3——3"DEF"
4——3"GHI"
5——3"JKL"
6——3"MNO"
7——4"PQRS"
8——3"TUV"
9——4"WXYZ"
并且两个数字是相乘关系
(2)算法构造:
递归出口是,当输入的是一个数字时,返回这个数字所有可能性的组合,递归体是当输入一串数字,每个数字代表不同的字符串,返回最后一个数字跟前面已产生的字符串进行组合,首先建一个数组,用来存放每个数字代表的字符串组合,然后再建一个数组,用来存放每个字符串的长度
(3)代码实现:



/*

Author:王连霞

date:2018-11-15

version:1.0

desciption:电话号码对应的字符组合:

在电话或者手机上,一个数字如2对应着字母ABC,7对应着PQRS。

那么数字串27所对应的字符的可能组合就有3*4=12种(如AP,BR等)。

现在输入一个3到11位长的电话号码,

请打印出这个电话号码所对应的字符的所有可能组合和组合数。

*/
#include<iostream>
using namespace std;
char*letter[10]={"","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};    //存放每个数字对应的字母

int  num[10]={0,0,3,3,3,3,3,4,3,4};      //表示0-9对应字母的个数
char input[15];
char output[15];
void RS(int t,int   length)   //递归函数
{    
   if(t == length)          //递归出口,当输入的是一个数字时,返回这个数字所有可能性的组合
    {        
           cout<<output<<endl;    
    }   
    for(int i=0; i<num[input[t]]; i++)    //递归体,输入一串数字,每个数字代表不同的字符串,返回最后一个数字跟前面已产生的字符串进行组合 
    {        
           output[t] = letter[input[t]][i];        
           RS(t+1,length);    
    }
}
int main()
{   
    int length;    
    printf("输入一个3到11位长的电话号码:");    
    scanf("%s",input);     
    printf("该电话号码所对应字符的所有可能的组合是:\n");   
    length = strlen(input);    
    int total = 1;    
    for(int i=0; i<length; i++)    
    {        
           input[i] -= '0';       
           total *= num[input[i]];   
    }    
    RS(0,length);    
    cout<<"组合数:"<<total<<endl;   
    return 0;
}

(4)运行结果:
在这里插入图片描述
4.

4.日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完 后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?

(1)题目分析

每个儿子的橘子数目有两种,原有的和现有的,除了老大,其他的儿子原有的+别人给的-给别人的=平均数,所以原有的=现有的+给别人的-别人给的。

大儿子得到六儿子之前的是:大儿子原有的-给二儿子的(1/8)=现有的-别人给的;

六儿子现有的(ave)=(六儿子原有的+别人给的)(2/3),所以,( 7/8大儿子原有的)=现有的-六儿子给的,所以大儿子现有的=得到六儿子之前的8/7倍。

(2)算法构造
//c[i][0]表示第i个儿子分出去桔子的总数,c[i][1]表示第i个儿子从父亲出得到桔子的总数

    c[i][1] = (ave - ave /2)*(8 - i) / (8- 1 - i);
    c[i][0] =c[i][1] - (ave- ave / 2);      (i=0)
    c[i][1] = ave*(8 - i) / (8 - 1 - i)-orange(c, i - 1); 
    c[i][0] = c[i][1] +orange(c, i - 1) - ave;   (0<i<6)
    (3)代码实现:


/*
Author:王连霞
date:2018-11-15
version:1.0
desciption:日本著名数学游戏专家中村义作教授提出这样一个问题:
父亲将2520个桔子分给六个儿子。分完
后父亲说:
"老大将分给你的桔子的1/8给老二;
老二拿到后连同原先的桔子分1/7给老三;
老三拿到后连同原先的桔子分1/6给老四;
老四拿到后连同原先的桔子分1/5给老五;
老五拿到后连同原先的桔子分1/4给老六;
老六拿到后连同原先的桔子分1/3给老大"。
结果大家手中的桔子正好一样多。问
六兄弟原来手中各有多少桔子? 
*/
#include<iostream>  
using namespace std;
int c[5][2] = { {0,0},{ 0,0 },{ 0,0 },{ 0,0},{ 0,0 } };
int orange(int c[5][2], int i)
{       int ave = 420;   
if (i == 0)          //递归出口              
{        
         //c[i][0]表示第i个儿子分出去桔子的总数,c[i][1]表示第i个儿子从父亲出得到桔子的总数
         //第一个儿子从父亲那里得到桔子数为:平均数减去最后一个孩子分出去的部分后乘以8/7
        c[i][1]= (ave - ave /2)*(8 - i) / (8- 1 - i);
        c[i][0]= c[i][1] - (ave- ave / 2); //第一个孩子分给第二个孩子的桔子数量
         }
         else      //递归体
         {        
                   c[i][1]= ave*(8 - i) / (8 - 1 - i) - orange(c, i - 1);//第i个儿子从父亲那里得到桔子总数               
             c[i][0] = c[i][1] + orange(c, i - 1) - ave;//第i个儿子分给下一个儿子的橘子数量
}        
      return      c[i][0];
}
void main()
{
         orange(c,5);
         cout<<"父亲最初分配桔子情况如下"<<endl;      
for (int i = 0; i<=5; i++)
         {                 
         cout<<"原来第"<<i+1<<"个儿子从父亲那里得到"<<c[i][1]<<"个桔子"<<endl;
}
for ( i = 0; i<=5; i++)
{
       cout<<"第"<<i+1<<"个儿子向下一个儿子分出"<<c[i][0]<<"个桔子"<<endl;
}
}

(4)运行结果:
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值