2021计算导论第八次练习题目

本文介绍了多个使用递归算法解决数值计算问题的例子,包括递归求值、序列求和、最大值查找、二进制转换、位数计算、数列求值、最大公约数计算以及整数逆序输出。每个问题都通过递归函数实现,避免了全局变量的使用,展示了递归在解决复杂问题时的有效性和简洁性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6-8 实验6_1_递归求值一 (100 分)

现有函数f(n),n为大于等于0的整数。当n等于0时f(n) = 0,当n大于0时 f(n)=f(n-1) +n3

注意:此题要求用递归求解,且不允许使用全局变量,否则没有分。

函数接口定义:

int    fuc(int n) ;

其中 n 是用户传入的参数。 n 的值不超过200。函数的返回值为对应的f(n)的计算结果。

裁判测试程序样例:

#include<stdio.h>

int    fuc(int n) ;

int main()
{
    int n ;

    scanf("%d",&n); 
    printf("%d\n",fuc(n));

    return 0 ;
}

/* 请在这里填写答案 */

输入样例:

2

输出样例:

9
int fuc(int n)
{
    if(n==0)
    {
        return 0;
    }
    else
    {
        return(fuc(n-1)+n*n*n);
    }
}

6-9 实验6_2_递归求值二 (100 分)

现有序列: s = a + a + 3 + a + 6 +…+ a + 3 X n

请写出递归求s的程序。

输入只有一行,为两个用空格分隔正整数,分别代表n(0<n) 和 a(1<a)

输出也只有一行,为此情况下s的值。(测试用例保证所有整数可以用 int存储)。

注意:此题要求递归求解,且不允许使用全局变量,其他方式不得分。

函数接口定义:

int getSum(int n , int a) ;

其中 n 和 a 都是用户传入的参数。 函数须计算结果。

裁判测试程序样例:


#include <stdio.h>

int getSum(int n , int a) ;

int main()
{
       int        n , a ; 

       scanf( "%d%d" , &n , &a );       
       printf( "%d\n" , getSum( n , a ) );

    return 0;
}

/* 请在这里填写答案 */

输入样例:

1 2

输出样例:

7
int getSum(int n , int a)
{
    if(n==0)
        return(a);
    else
    {
        return(a+3*n+getSum( n-1 , a ));
    }
}

6-10 实验6_3_递归求最大值 (100 分)

写一个函数可以读入n(0<n<100)个整数,并求出这n个整数中的最大值。

此题要求递归求解,且不允许使用全局变量。在此题的所有提交中只要出现非递归提交,无论其他提交是否是递归求解此题均为0分。

函数接口定义:

int findMax(int n) ;

其中 n 是用户传入的参数。 n 的值大于0且小于100; 函数须返回 读入的n个整数中最大的那个数。

裁判测试程序样例:

#include <stdio.h>

int findMax(int n) ;

int main()
{   
    int n ; 

    scanf("%d", &n); 
    printf("%d\n" , findMax( n ) ) ; 

    return 0;
}

/* 请在这里填写答案 */

输入样例:

6
15  30  34  10  89 5

输出样例:

89
//递归前进段:只下探;递归返回段:读取值并比较
int findMax(int n)
{
    int max,now;
    if(n==1)
    {
        scanf("%d",&max);
        return(max);
    }
    else
    {
        now=findMax(n-1);
        scanf("%d",&max);
        return(max>now?max:now);
//务必将findMax(n-1)先赋值给一个变量,再对该变量进行return操作
//因为若调用两次递归函数,导致最后最后的一次甚至多次调用将无读入值,机器一直在等待用户写入新值,直到超时停止等待
//错误示例:
//        return(max>findMax(n-1)?max:findMax(n-1));
    }
}
//20220115
//递归前进段:读取值;递归返回段:依次比较
int findMax(int n){
    int m,max;
    scanf("%d",m);
    if(n==1){
        return  m;
    } else{
        max= findMax(n-1);
        if(max>m){
            return max;
        } else{
            return m;
        }
    }
}

6-11 实验6_4_二进制转十进制 (100 分)

设计递归函数int convert(int n);用于将二进制数n转换为十进制数并返回。 递归函数设计思路与提示: 如将1101转换为十进制的形式:

1101=1 * 20 + 0 * 21 + 1 * 22 + 1 * 23 = 1101 % 10 + convert(110) * 2 ;

110 = 0 * 20 + 1 * 21 + 1 * 22 = 110 % 10 + convert(11) * 2;

11 = 1 * 20 + 1 * 21 = 11 % 10 + convert(1) * 2 ;

convert(1) = 1 ;

所以得到以下结论:当n==0或n==1时,函数返回n,否则返回n%10+convert(n/10)*2 。

输入与输出要求: 输入一个整数n,代表二进制数,其长度不大于10。输出转换后的十进制数,占一行。

注意:此题要求递归求解,且不允许使用全局变量,其他方式不得分。

函数接口定义:

int convert(int n);

其中 n 是用户传入的参数。 n 的长度不大于10;函数的返回值为转换后的十进制数。

裁判测试程序样例:

#include<stdio.h>

int convert(int n);

int main()
{
    int        n ;

    scanf("%d",&n);

    printf("%d\n",convert(n)) ;
    return 0 ;    
}

/* 请在这里填写答案 */

输入样例:

101010

输出样例:

42
int convert(int n)
{
    if(n==0||n==1)
        return(n);
    else
        return n%10+convert(n/10)*2;
}

6-12 实验6_5_二进制的位数 (100 分)

设计递归函数int countBinary(int n); 用于将非负十进制整数n转换成二进制形式,并返回该二进制数的位数。如十进制数13的二进制形式为1101,位数为4,那么调用countBinary(13)的结果为4。

要求同学们先写出该问题的递归定义式,再设计递归函数。

输入与输出要求: 输入一个非负整数n。输出求得的结果,如输入“13”,输出“4”,占一行。

注意:此题要求递归求解,且不允许使用全局变量,其他方式不得分。

函数接口定义:

int countBinary(int n);

其中 n 是用户传入的参数。 n 的值不超过int的范围。函数的返回值为 n的二进制形式的位数。

裁判测试程序样例:

#include<stdio.h>

int countBinary(int);

int main()
{
    int        n;

    scanf("%d",&n);
    printf("%d\n",countBinary(n));

    return 0 ;
}

/* 请在这里填写答案 */

输入样例:

13

输出样例:

4
分析:十进制数能够除以多少个10,就是几位数;同理,二进制数能够除以多少个2,就是几位数
int countBinary(int n)
{
    int a,len=0;
    a=n;
    if(a<=1)
        return 1;
    else
    {
        return countBinary(n/2)+1;
    }
}

6-13 实验6_6_数列求值 (100 分)

现有序列: s = 1 + a + a2 +…+ an+1

其中a>0,n>0,且均为整数。 测试用例保证所有整数可以用int存储。 请写出递归求s的函数。

注意:此题要求递归求解,且不允许使用全局变量,其他方式不得分。

函数接口定义:

int evaluation(int n,int a);

其中 n 和 a 都是用户传入的参数,分别代表数列中的n和a,返回值为所求结果。

裁判测试程序样例:

#include <stdio.h>

int    evaluation(int n,int a) ;
int main()
{
       int        n , a ; 

       scanf("%d%d",&n,&a);       
       printf("%d\n",evaluation(n,a));

    return 0;
}

/* 请在这里填写答案 */

输入样例:

1 2

输出样例:

7
//依次直接加上每一项
#include<math.h>
int evaluation(int n,int a)
{
    if(n==0)
        return a+1;
    else
        return pow(a,n+1)+evaluation(n-1,a);//请注意这是pow函数而非power函数
}
//20220115每次最外面乘个a,实现幂次递增
int evaluation(int n,int a)
{
    if(n>=0)
        return evaluation(n-1,a)*a+1;
    else
        return 1;
}

6-14 实验6_7_最大公约数 (100 分)

设计递归函数int GCD(int a,int b);计算正整数a和b的最大公约数并返回。如GCD(32,48)为16。

GCD(a,b)递归定义为:

GCD(a,b)=GCD(b,a MOD b) 当 a MOD b≠0

GCD(a,b)=b 当 a MOD b=0

输入与输出要求: 输入两个正整数a和b,输出两数的最大公约数,占一行。

注意:此题要求递归求解,且不允许使用全局变量,其他方式不得分。

函数接口定义:

int GCD(int a , int b );

其中 a 和 b 都是用户传入的参数。a 和 b 的值不超过int的范围。函数的返回值为a 和 b 的最大公约数。

裁判测试程序样例:

#include<stdio.h>

int GCD(int a , int b );

int main()
{
    int        a , b ;

    scanf("%d%d", &a , &b );
    printf( "%d\n" , GCD( a, b ) ) ;

    return 0 ;    
}

/* 请在这里填写答案 */

输入样例:

32 48

输出样例:

16
int GCD(int a , int b )
{
    int c;
    if(a%b==0)
        return b;
    else
    {
        c=b;
        b=a%b;
        a=c;//完全没有必要专门调换顺序
        return GCD(a,b);
    }
}
//20220115
int GCD(int a ,int b){
    if (a%b==0)
        return b;
    else
        return GCD(b,a%b);
}

6-15 实验6_8_整数逆序输出 (100 分)

请写出将一个整数逆序输出的函数。

注意:此题要求递归求解且不允许使用数组,不允许使用全局变量。如果违反要求则没有分。

函数接口定义:

void reverse(int n) ;

其中 n 是用户传入的参数。 n 的值大于0且不超过int的范围; 函数的返回值为空,其功能是逆序输出 n。测试用例保证输入的n末尾不为0。

裁判测试程序样例:

#include <stdio.h>

void reverse(int n) ; 

int main()
{
    int     n;

    scanf("%d",&n);
    reverse(n) ;
    printf("\n");
    return 0;
}

/* 请在这里填写答案 */

输入样例:

1234

输出样例:

4321
void reverse(int n)
{
    if(n/10==0)
        printf("%d",n);
    else
    {
        printf("%d",n%10);
        reverse(n/10);//请注意这是一个没有返回值的函数,所以不可以在printf里面调用它,只能单独开来写
    }
}

6-16 实验6_9_素数分解 (100 分)

设计递归函数void void printFactor( int, int );打印出对n进行素数分解的结果。

当执行void printFactor(60,1)时,打印效果为:

60=2*2*3*5。

关于素数分解的描述,见讲义。

设计程序,已知一段数据范围[a,b],且a<=b,要求对其中的每一个数进行素数分解。你也可以设计其它辅助函数,如判断素数的函数isPrime(n)。

输入与输出要求: 输入两个正整数a、b,代表所分解的区间,满足1<=a<=b<=100000,且b-a<=100。输出b-a+1行,即b-a+1个数的分解。

注意:此题要求递归求解,且不允许使用全局变量,其他方式不得分。

函数接口定义:

void printFactor( int, int ); 

其中第一个参数为待分解的整数,第二个参数需自行设计。函数无返回值。

裁判测试程序样例:

#include<stdio.h>

void printFactor( int, int ); 

int main()
{
    int a,b,i ;

    scanf( "%d%d", &a, &b );
    for( i = a ; i <= b ; i++ )
        printFactor( i , 1 ) ;    

    return 0;
}

/* 请在这里填写答案 */

输入样例:

100 105

输出样例:

100=2*2*5*5
101=101
102=2*3*17
103=103
104=2*2*2*13
105=3*5*7
//每次打印"因子*",单独处理最后一个数字
int isPrim(int a)
{
    int i;
    for(i=2;i*i<=a;i++)
    {
        if(a%i==0)
            return 0;
    }
    return 1;
}

void printFactor( int m, int n)
{
    int i;
    if(n==1)//首次进入递归打印
    {
        printf("%d=",m);
    }
    if(isPrim(m))//待分解数如果是个质数,那么直接打印它就好了
    {
        printf("%d\n",m);
    }
    else//待分解数不是质数,继续递归分解
    {
        for( i = 2 ; i*i <= m ; i++ )
        {
            if(m%i==0)
                break;
        }
        printf("%d*",i);
        printFactor( m/i , i ) ;
    }
}

//20220115
//每次打印"*因子",单独处理首个数字
//注意:本方法不用进行素数的判断,因为在遇见和数之前,一定会碰到这个和数的因子,所以其实碰不到和数
void printFactor( int n, int a){
    int i,t;
    if(a==1) //只有第一次调用时才执行这一部分,打印等号左边的部分和第一个因子
    {
        printf("%d=", n);
        for ( i = 2; ; ++i) {
            if (n % i == 0) {
                printf("%d", i);
                t=n/i;
                break;
            }
        }
    } else
        t=n;

    //该数字已分解完成,换行并直接返回
    if (t==1) {
        printf("\n");
        return ;
    }
    //该数字未完成分解,需要继续递归前进
    else{
        for ( i = 2;  ; ++i) {
            if (t%i==0) {
                printf("*%d", i);
                break;
            }
        }
        printFactor(t/i,2);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值