递归算法典例



1、一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子
题目分析:
      递归终止的条件是当达到第7个村庄时递归停止,设每经过一个村庄剩余的鸭子数为sum = sum-(sum/2+1)
算法构造:

       当 n=7 时 sum = 2;当 0<n<7 时 sum =2*m+2;

//题目:递归算法解决卖鸭子问题
//作者 :软工1508010205YL
//时间 : 2017/05/20

#include<stdio.h>
#include <iostream.h>
int duck(int,int);
void main()
{
	int sum = 2;//第7个村庄剩余的鸭子数为2
	int  n=7 ;//第7个村庄
	cout<<"鸭子总数:"<<duck(n,sum)<<endl;	
}
int duck(int n, int sum)
{
	if(n>0)
	{
		sum = 2*sum+2;//每个村庄剩余的鸭子数	
		if(n-1>0)
		{	
			cout<<"第"<<n-1<<"个村庄卖出的鸭子数"<<2*sum+2-sum<<endl;//第n-1个村庄卖出的鸭子数等于它原来剩余的数目减去第n个村庄剩余的鸭子数
		}
		n--;
		return duck(n,sum);		
	}
	else
	{
		return sum;
	}
}

运行截图:

2、角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以31。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1
题目分析:
  
递归的终止条件是最后值为1;先对输入的数n 进行判断,若 n = 1,则输出1;若输入的数为偶数, 则把它除以2;若为奇数则乘31;直到n = 1为止;
算法构造:
   n=1 , 输出1;若n%2==0(n为偶数)时,n = n/2;n%2==1(n为奇数)时,n = 3*n+1


//题目:递归算法解决角谷定理问题
//作者 :软工1508010205YL
//时间 : 2017/05/20

#include<iostream>
using namespace std;
int number(int n)
{
	if(n==1)//输入的数为1
	{
		cout<<1;
		return 1;
	}
	else if(n%2==0)//输入的数为偶数
	{
		cout<<n<<" ";
	    number(n/2);

	}
	else if(n%2==1)//输入的数为奇数
	{
		cout<<n<<" ";
        number(n*3+1);
	}
}
int main()
{
	int n,step;
	cout<<"******************************角谷定理******************************"<<endl;
	cout<<"输入一个自然数:";
	cin>>n;
	cout<<"输出:";
	step=number(n);//调用函数
	cout<<endl;
	return 0;
}

运行截图:

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

题目分析:

    2对应的是ABC , 3对应的是DEF ,4对应的是GHI,5对应的是JKL,6对应的是MNO, 7对应的是PQRS, 8对应的是TUV, 9对应的是WXYZ

//题目:递归算法解决电话号码对应的字符组合的问题
//作者 :软工1508010205YL
//时间 : 2017/05/20

#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};
char input[15];
char output[15];
void SL(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];
        SL(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]];
    }
    SL(0,length);
    cout<<"组合数:"<<total<<endl;
    return 0;
}

运行截图:

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

题目分析:

     由老大开始分给老二,当老大拿到老六的桔子后总数达到平均数,以此进行递推。 

算法构造:

    第一个儿子分到的桔子总数应为平均数减去最后一个孩子分出去的部分再乘以8/7

//题目:递归算法解决分桔子问题
//作者 :软工1508010205YL
//时间 : 2017/05/20

#include <stdio.h>  
#define DENO_MAX 8 //分母最大值
#define DENO_MIN 3//分母最小值
int Orange(int a[5][2],int i)
{  
	int average=2520/6;
	if (i==0)
	{  
		a[i][1]=(average-average/(DENO_MIN-1))*(DENO_MAX)/(DENO_MAX -1);//第一个儿子分到的桔子总数应为平均数减去最后一个孩子分出去的部分再乘以8/7
		a[i][0] = a[i][1] - (average-average/(DENO_MIN-1));//第一个儿子分给第二个儿子的桔子数
	}  
	else 
	{  
		a[i][1] = average *(DENO_MAX-i)/(DENO_MAX-1-i) - Orange(a,i-1);//第i个儿子分到的桔子总数
		a[i][0] = a[i][1] + Orange(a,i-1) - average; //第i个儿子分出去的桔子数 
	} 
	return a[i][0]; 
} 
void main() //主函数
{  
	int a[][2]={{0,0},{0,0},{0,0},{0,0},{0,0}}; 
	Orange(a,5); 
	printf("六个儿子原来分到的桔子总个数:\n"); 
	for(int j=0;j<=5;j++) 
	{ 
		printf("第%d个儿子: %d\n",j+1,a[j][1]); 
	} 
	getchar();
}
运行截图:







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值