本人能力有限,发出只为帮助有需要的人。
建议同学们自己写完后再进行讨论。
1.题目名称:排列组合
问题描述:编写程序求函数C(m,n)的值。
输入:从键盘随机输入一个自然数和一个非负整数,分别作为m和n的值(m≥n)。
输出:函数C(m,n)的值。
样例1:
输入:
4 1
输出:
4
样例2:
输入: 6 2 输出: 15
#include <stdio.h>
int combination(int m,int n)//组合数定义
{
if(n<0)
return 0;
else if(0==n)
return 1;
else if(1==n)
return m;
else if(m<2*n)
{
// printf("%d %d\n",m,m-n);//此行可以方便调试
return combination(m,m-n);
}
else if(m>=2*n)
{
// printf("%d %d %d %d\n",m-1,n-1,m-1,n);//此行可以方便调试
return combination(m-1,n-1)+combination(m-1,n);
}
}
int main(void)
{
int m,n;
scanf("%d %d",&m,&n);
printf("%d",combination(m,n));
return 0;
}
2. 题目名称:Hermite多项式
题目描述:编写程序,用递归方法求解Hermite 多项式值。Hermite 多项式定义如下。
输入:从键盘随机输入一个非负整数和一个实数,作为n和x的值。
输出:H~n~(x)的值,精确到小数点后2位。
样例1:
输入: 0 1.5
输出: 1.00
样例2:
输入: 2 2.4
输出: 21.04
#include <stdio.h>
double hermite(int n,double x)//注意x的输入为double型,输出也是double型
{
if(0==n)
return 1;
else if(1==n)
return 2*x;
else if(n>1)
return (2*x*hermite(n-1,x)-2*(n-1)*hermite(n-2,x));
}
int main(void)
{
int n;
double x;
scanf("%d %lf",&n,&x);//注意输入的类型
printf("%.2lf",hermite(n,x));
return 0;
}
3. 题目名称:Ackerman函数
问题描述:编写程序,计算 Ackerman 函数值。Ackerman 函数定义如下
输入:从键盘随机输入两个非负整数,分别作为m和n的值。
输出:Ack(m, n)的值。
样例1:输入 2 3 输出 9
样例2:输入 3 2 输出 29
样例3:输入 0 3 输出 4
#include <stdio.h>
int ack(int m,int n)
{
if(0==m)
return n+1;
else if(0==n)
return ack(m-1,1);
else if(m>0&&n>0)
return ack(m-1,ack(m,n-1));//递归进行两层的嵌套
}
int main(void)
{
int m,n;
scanf("%d %d",&m,&n);
printf("%d",ack(m,n));
return 0;
}
4. 题目名称:最大公因数
题目描述:编写程序,用递归方法求解m、n最大公约数。对正整数u和v 可以采用欧几里德辗转相除算法求它们的最大公因数,具体过程如下:
u% v → r~1~
v % r~1~ → r~2~
r~1~% r~2~ → r~3~
r~2~ % r~3~ → r~4~
… …
r~n-1~% r~n~ → r~n+1~=0
当余数r~n+1~=0时,计算过程结束,r~n~ 为正整数u 、v的最大公因数。
输入:从键盘随机输入两个正整数m和n。输出:最大公因数。
样例1:
输入: 12 15
输出: 3
样例2:
输入: 28 49
输出: 7
#include <stdio.h>
int euclid(int m,int n)
{
int r;
if(0==n)//递归的出口
return m;
else//欧几里得辗转相除
return euclid(n,m%n);
}
int main(void)
{
int m,n;
scanf("%d %d",&m,&n);
printf("%d",euclid(m,n));
return 0;
}
5. 题目名称:顺序检索
题目描述:编写程序,用递归方法在整数组中进行顺序检索。
输入:
第一行输入一个正整数n(0<n≤100),表示数组的元素个数;
第二行依次输入n个整数,作为数组的元素;
第三行输入待检索的关键字。
输出:
如果数组中含有关键字,则输出其首次出现的位置(下标值较小的位置)否则输出NULL。
样例1:
输入: 8 0 2 3 4 5 9 10 8 3
输出: 2
样例2:
输入: 8 0 2 3 4 5 9 10 8 6
输出: NULL
#include <stdio.h>
int search(int flag,int n,int x,int *p)//由于函数类型为整型,所以不能直接输出NULL
{
if(*(p+flag)==x)//输入指针代替输入数组
return flag;//flag为数组下标
else if(flag==n)//没找到检索关键字
return -1;//用-1代替NULL(n为正整数)
else
{
// printf("%d %d %d\n",flag+1,n,x);//输出递归的参数方便调试
return search(flag+1,n,x,p);//下标加一再次递归
}
}
int main(void)
{
int a[200],i,n,x,flag=0,result;//flag为数组下标
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",a+i);
scanf("%d",&x);
result=search(flag,n,x,a);
if(result==-1)//将-1转化为NULL
printf("NULL");
else
printf("%d",result);
return 0;
}
6.题目名称:最大元素
题目描述:编写程序,用递归方法求解长度为n的整型数组中最大元素值。
输入:第一行输入一个正整数n(0<n≤100),表示数组的元素个数;第二行依次输入n个整数,作为数组的元素。
输出:最大元素的值。
样例1:
输入: 10 9 8 7 6 5 4 3 2 1 0
输出: 9
样例2:
输入: 10 0 1 2 3 4 5 6 7 8 9
输出: 9
#include <stdio.h>
int result=0,p[100];//可以将数组的指针p设置为全局变量
int max(int flag,int n)//flag为数组下标
{
if(flag==n)
return result;
else if(*(p+flag)>result)
{
result=*(p+flag);
return max(flag+1,n);
}
else
return max(flag+1,n);//下标加一再次递归
}
int main(void)
{
int i,n,flag=0;//flag为数组下标
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",p+i);
printf("%d",max(flag,n));
return 0;
}
7. 题目名称:数组反序
题目描述:编写程序,用递归方法反序数组。
输入:第一行输入一个正整数n(0<n≤100),表示数组的元素个数;第二行依次输入n个整数,作为数组的元素。
输出:顺次输出逆序后数组中元素,元素间以一个西文空格间隔,最后一个元素后无字符。
样例1:
输入: 8 0 2 3 4 5 9 10 8
输出: 8 10 9 5 4 3 2 0
样例2:
输入: 5 0 2 3 3 5
输出: 5 3 3 2 0
#include <stdio.h>
int p[200],q[200];//p为原始数组,q为逆序后的数组
void reverse(int flag,int n)//空类型函数的递归
{
if(flag!=n)
{
q[flag]=p[n-flag-1];
reverse(flag+1,n);//不需要返回值
}
}
int main(void)
{
int i,n,flag=0,tem;//flag为数组下标
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",p+i);
reverse(flag,n);
flag=0;
for(i=0;i<n;i++)//输出数组q
{
if(flag)
printf(" ");
flag=1;
printf("%d",q[i]);
}
return 0;
}
8. 题目名称:截木条
题目描\述:
给定一个长度为n的木条,将其在大致2/5的位置截断,得到2个长度仍为整数的木条;如果新得到的木条的长度仍旧超过规定长度k,将继续按照上述方法处理得到的木条,直到所有木条的长度都不大于k。
编写程序,用递归方法计算一个长度为n的木条,当规定长度为k时,其经过上述截断过程会得到多少根木条。其中:n、k均为正整数,且假设木条截断所得短木条长度四舍五入为正整数,长木条长度为总长减去短木条长度。
输入:顺次从键盘输入两个正整数n和k。
输出:木条根数。
#include <stdio.h>
void cut(int n,int k,int *p)//用指针输出可以规避返回值的计算
{
(*p)++;//输入指针后函数就有权改变指向的数
if((int)(2.0/5.0*n+0.5)>k)//用(int)(a+0.5)进行四舍五入
cut((int)(2.0/5.0*n+0.5),k,p);//p是切割的次数
if((int)(3.0/5.0*n+0.5)>k)
cut((int)(3.0/5.0*n+0.5),k,p);
}
int main(void)
{
int n,k,flag=1;//本身就有一根木棍,所以初始值为1
scanf("%d %d",&n,&k);
cut(n,k,&flag);
if(n<=k)//n<=k的情况单列出来
printf("1");
else
printf("%d",flag);
return 0;
}
9. 题目名称:十进制转换任意进制
题目描述:编写程序,用递归方法将十进制的非负整数 N 转换为 b 进制数(2≤b≤36),其中字符、ASCII码值和数值之间的对应关系如下:
输入:一行输入两个非负整数,分别是十进制的 N 和 b ,其中 0 <=N <=2^31 ,2 <=b <= 36 。
输出:N 的 b 进制数。
样例1:
输入: 579 8
输出: 1103
样例2:
输入: 579 20
输出: 18J
#include <stdio.h>
void decimal(long long x,int n)
{
long long p;//p为x对n取余
if(x>=n)
{
decimal(x/n,n);//先进行递归操作,改变输出顺序
p=x%n;
if(p<=9)
printf("%c",p+48);//题目中给了ascii转换,事实上也可以用'0'-0得到
if(p>=10)
printf("%c",p+55);//ascii转换要跳过小写字母
}
if(x<n)//x<n时,x%n的操作失效,所以单独提出来
{
if(x<=9)
printf("%c",x+48);
if(x>=10)
printf("%c",x+55);
}
}
int main(void)
{
long long x;//题目要求X<=2^31所以用long long型
int n;
scanf("%lld %d",&x,&n);
decimal(x,n);
return 0;
}