山东理工大学:PTA实验七:参考答案与解析(2023)

  如题,在学习的过程中做些记录,会持续更新到结束(咕咕咕?)。希望能对自己和大家有所帮助。

0-0*********目录****************

目录

0-0*********目录****************

6-1 sdut-C语言实验-计算组合数

1.题目

2.参考代码 

3.解析或补充

6-2 sdut- C语言实验——矩阵下三角元素之和

1.题目:

2.参考代码:

3.解析或补充

6-3 sdut-C语言实验- N!

1.题目

2.参考代码

6-4 sdut-C语言实验-使用函数验证哥德巴赫猜想

1.题目

2.参考代码

3.解析或补充

6-5 sdut-C语言实验- 求数列的和

1.题目

2.参考代码

3.解析或补充

6-6 递归实现顺序输出整数

1.题目

2.参考代码

3.解析或补充

7-1 sdut- C语言实验—计算表达式

1.题目

2.参考代码

7-2 sdut-C语言实验- 计算题

1.题目

2.参考代码

3.解析或补充

7-3 sdut-C语言实验-斐波那契数列

1.题目

2.参考代码

7-4 求组合数 

1.题目

2.参考代码 

7-5 求算式的和[1] 

1.题目

2.参考代码 

7-6 计算圆柱体的体积 

1.题目

2.参考代码 

3.解析或补充

7-7 出生年 

1.题目

2.参考代码 



6-1 sdut-C语言实验-计算组合数

1.题目

计算组合数。C(n,m),表示从n个数中选择m个的组合数。
计算公式如下:
若:m=0,C(n,m)=1
否则, 若 n=1,C(n,m)=1
否则,若m=n,C(n,m)=1
否则 C(n,m) = C(n-1,m-1) + C(n-1,m).

函数接口定义:

在这里描述函数接口。
例如:

int fun(int n,int m);

其中 n 和 m 都是用户传入的参数(0 <= m <= n <= 20)。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>
int fun(int n,int m);

int main()
{
 int t,n,m,i;
 scanf("%d",&t);
 for(i=1;i<=t;i++)
 {
     scanf("%d %d",&n,&m);
     printf("%d\n",fun(n,m));
 }
    return 0;
}

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

输入样例:

在这里给出一组输入。例如:

3
2 1
3 2
4 0

输出样例:

在这里给出相应的输出。例如:

2
3
1

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB  

2.参考代码 

/*@Keywords of Code: 函数基础知识
* @Author: 毛毛maomaonwn
* @Date: 2023/12/8
*/



int fun(int n, int m) {
    if (m == 0) {
        return 1;                   
    }
    else if (n == 1) {
        return 1;
    }
    else if (m == n) {
        return 1;
    }
    else {
        return fun(n - 1, m - 1) + fun(n - 1, m);            //函数自己可以调用自己
    }
}

3.解析或补充

        1. 函数基础知识概述:

  • 函数:函数是一个程序块
  • 函数的定义:

返回值类型 函数名(形式参数){

                  代码

                  return表达式

}

其中,如果不书写return表达式的话,返回值类型要写void(”空,无”)。

  • 参数:分为形式参数和实际参数,没有实际值的参数是形参,有实际值的则为实参。参数的语法是:数据类型 变量名
  • 函数的声明:提前让编译器了解到函数的存在。语法是:返回值类型 函数名(形式参数)

        2.函数可以自己调用自己,这也是递归的一种简单体现

6-2 sdut- C语言实验——矩阵下三角元素之和

1.题目:

输入一个正整数n(1<=n<=10),再输入n*n的矩阵,要求求该矩阵的下三角元素之和。

函数接口定义:

int f(int (*p)[10],int n);

其中 p 和 n 都是用户传入的参数。 p 的值为地址; n 是[1, 10]区间内的个位数。函数不需要返回数据。

裁判测试程序样例:


#include<stdio.h>
int  f(int (*p)[10],int n);

int main()
{
    int n,i,j,sum;
    int a[10][10];
    scanf("%d",&n);
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    sum=f(a,n);
    printf("%d",sum);
    return 0;
}


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

输入样例:

5
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9

输出样例:

75

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码:

/*@Keywords of Code:循环的范围、地址传递
  @Author:毛毛maomaonwn
  @Date:2023/12/9
*/


//在解答这题前,需要正确了解“下三角”和“上三角”是什么样的:
/*“下三角”形:
*
**
***
****
  “上三角”形:
****
 ***
  **
   *
*/



int f(int(*p)[10],int n){            //二维数组的传递——指针形式
    int sum = 0;
    for(int i=0;i<n;i++){           
        for(int k=0;k<=i;k++){
            sum+=p[i][k];
        }
    }
    return sum;
}

3.解析或补充

        1.循环的范围:

数据模拟:

     

        2.二维数组的地址传递——指针形式

函数声明:

void arr_fun(int (*arr)[col],int col);     //1.col代表列数,在多维数组中,第一维是可以省略的。
      

/*2.请注意正确书写(int (*arr)[col]),而不是(int arr[col])。前者是数组的指针,后者是指针数组,它们并不相同。*/
  

函数调用:

arr_fun(arr,col);

//这里一定是写数组名arr,因为我们是要传递整个数组。

更多的知识:

     如果你还想了解直接传递二维数组传递二级指针的表述,可以参考这篇优秀的博客!二维数组的函数传参分析_二维数组传参-CSDN博客

6-3 sdut-C语言实验- N!

1.题目

给出两个数 n, m。求
 

1.png



 

2.png



计算公式:

3.png


输入数据有多组(数据组数不超过 250),到 EOF 结束。

对于每组数据,输入两个用空格隔开的整数 n, m (0 <= m <= n <= 20) 。
对于每组数据输出一行,
 

1.png



 

2.png


,用空格隔开。

提醒:因为n!和 m! 数据较大,定义数据类型应用 long long int,输出格式%lld

函数接口定义:

long long int f(long long int n);

其中 n 是用户传入的参数。函数须返回n!的值。

裁判测试程序样例:


#include <stdio.h>
long long int f(long long int n);
int main()
{
    long long int n,m,i;
    while(~scanf("%lld %lld",&n,&m))
    {
        long long int a,c;
        a=f(n)/f(n-m);
        c=f(n)/f(n-m)/f(m);
        printf("%lld %lld\n",a,c);
    }
    return 0;
}

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

输入样例:

在这里给出一组输入。例如:

1 1
5 3
4 3

输出样例:

在这里给出相应的输出。例如:

1 1
60 10
24 4

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

long long int f(long long int n){
    int out = 1; 
    for(int i=1;i<=n;i++){
        out*=i;
    }

    return out;
}

6-4 sdut-C语言实验-使用函数验证哥德巴赫猜想

1.题目

本题要求实现一个判断素数的简单函数,并利用该函数验证哥德巴赫猜想:任何一个不小于6的偶数均可表示为两个奇素数之和。素数就是只能被1和自身整除的正整数。输入一个不小于6的偶数n,找出两个素数,使它们的和为n。注意:1不是素数,2是素数。

函数接口定义:

int isPrime( int x ); 
void Goldbach( int n );

其中函数isPrime当用户传入参数x为素数时返回1,否则返回0;函数Goldbach按照格式“n=p+q”输出n的素数分解,其中p≤q均为素数。又因为这样的分解不唯一(例如24可以分解为5+19,还可以分解为7+17),要求必须输出所有解中p最小的解。

裁判测试程序样例:


#include <stdio.h>
int isPrime( int x );
void Goldbach( int n );
int main()
{
    int n;
    scanf("%d",&n);
    if(n%2==0)
        Goldbach( n );
    return 0;
}

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

输入样例:

80

输出样例:

80=7+73

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

/*@Keywords of Code:素数的算法、理解哥德巴赫猜想
  @Author:毛毛maomaonwn
  @Date:2023/12/15 */
                    



int isPrime(int x){
    int judge = 1;                                          //素数的算法:原理见下
    for(int i=2;i<x/2;i++){          
        if(x%i==0){
            judge = 0;
            break;                                          
        }
    }

    return judge;
}



void Goldbach(int n){
    for(int i=3;i<n;i++){                                  //从3开始循环是因为是求"奇素数"
        if(isPrime(i)==1 && isPrime(n-i)==1){
            printf("%d=%d+%d",n,i,n-i);
            break;
        }
    }
}

3.解析或补充

        1.break语句:

使跳出当前循环。如果是嵌套循环,则跳出最近的循环。

        2.素数的算法:

6-5 sdut-C语言实验- 求数列的和

1.题目

数列的定义如下: 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和。
提示:因为自定义函数中用到数学函数,因此本题目的提交答案需要包括头文件在内的主函数和自定义函数。

函数接口定义:

double s(double n,int m);

其中 n 和 m 都是用户传入的参数。 n 的值不超过double的范围; m 的值不超过int的范围。函数须返回数列前m项的和。

提示:本题需要在自定义函数中使用sqrt()数学函数,因此在填写答案时需要提交完整的程序,既题目已经给定的代码部分和需要填写的答案部分。

裁判测试程序样例:

#include <stdio.h>
#include <math.h>

double s(double n,int m);

int main()
{
    int a,b,m,i;
    double sum,n;
    while (scanf("%lf %d",&n,&m)!=EOF)
    {
        sum=s(n,m);
        printf("%.2lf\n",sum);
    }

    return 0;
}


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

输入样例:

81 4
2 2

输出样例:

94.73
3.41

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

/*@Keywords of Code:sqrt函数
  @Author:毛毛maomaonwn
  @Date:2023/12/15 */



#include <stdio.h>
#include <math.h>

double s(double n,int m);

int main()
{
    int a,b,m,i;
    double sum,n;
    while (scanf("%lf %d",&n,&m)!=EOF)
    {
        sum=s(n,m);
        printf("%.2lf\n",sum);
    }

    return 0;
}

double s(double n,int m){
    double sum = 0;

    for(int i=0;i<m;i++){
        sum+=n;
        n=sqrt(n);
    }

    return sum;
}

3.解析或补充

        1.pow函数和sqrt函数

6-6 递归实现顺序输出整数

1.题目

本题要求实现一个函数,对一个整数进行按位顺序输出。

函数接口定义:

void printdigits( int n );

函数printdigits应将n的每一位数字从高位到低位顺序打印出来,每位数字占一行。

裁判测试程序样例:

#include <stdio.h>

void printdigits( int n );

int main()
{
    int n;
    
    scanf("%d", &n);
    printdigits(n);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

12345

输出样例:

1
2
3
4
5

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

/*@Keywords of Code:递归
  @Author:毛毛maomaonwn
  @Date:2023/12/15 */


//该题标题为“递归实现顺序输出整数”,因此以下我们使用递归的方式来解决

void printdigits(int n){

    if(n/10==0){                    //包含数字是0的特殊情况
        printf("%d\n",n);
        return;
    }

    printdigits(n/10);
    printf("%d\n",n%10);
}

3.解析或补充

        1.递归

  • 将复杂的事物分解为简单的重复的思想
  • 书写递归的步骤(思考的顺序可以变化):1.函数功能,2.递归结束条件,3.递归传递表达式

7-1 sdut- C语言实验—计算表达式

1.题目

计算下列表达式值:

1199.jpg

输入格式:

输入x和n的值,其中x为非负实数,n为正整数。

输出格式:

输出f(x,n),保留2位小数。

输入样例:

3 2

输出样例:

在这里给出相应的输出。例如:

2.00

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

/*@Keywords of Code:理解表达式
  @Author:毛毛maomaonwn
  @Date:2023/12/17 */

#include<stdio.h>
#include<math.h>

double culc(double x,int n);

int main(){
    double x;
    int n;
    double out;
    scanf("%lf %d",&x,&n);



    out = culc(x,n);
    

    
    printf("%.2lf",out);
    
}

double culc(double x,int n){            //可以根据代码列一遍数据来理解

    if(n==1){
        return sqrt(1+x);
    }

    return sqrt(n+culc(x,n-1));
}

7-2 sdut-C语言实验- 计算题

1.题目

一个简单的计算,你需要计算f(m,n),其定义如下:
当m=1时,f(m,n)=n;
当n=1时,f(m,n)=m;
当m>1,n>1时,f(m,n)= f(m-1,n)+ f(m,n-1)

输入格式:

第一行包含一个整数T(1<=T<=100),表示下面的数据组数。
以下T行,其中每组数据有两个整数m,n(1<=m,n<=2000),中间用空格隔开。

输出格式:

对每组输入数据,你需要计算出f(m,n),并输出。每个结果占一行。

输入样例:

在这里给出一组输入。例如:

2
1 1
2 3

输出样例:

在这里给出相应的输出。例如:

1
7

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

/*@Keywords of Code:基础运用
  @Author:毛毛maomaonwn
  @Date:2023/12/17 */

#include<stdio.h>

int func(int m,int n);

int main(){
    int T;
    int m,n;
    scanf("%d",&T);

    while(T--){                        //输入多组数据
        scanf("%d %d",&m,&n);

        printf("%d\n",func(m,n));       
    }

    return 0;
}

int func(int m,int n){
    if(m==1){
        return n;
    }
    else if(n==1){
        return m;
    }
    else if(m>1 && n>1){
        return func(m-1,n)+func(m,n-1);
    }
    else return;
}

3.解析或补充

        1.循环条件:while(n)与while(n--)

7-3 sdut-C语言实验-斐波那契数列

1.题目

编写计算斐波那契(Fibonacci)数列的第n项函数fib(n)(n < 40)。
数列描述:
f1=f2==1;
fn=fn-1+fn-2(n>=3)。

输入格式:

输入整数 n 的值(0 < n < 40)。

输出格式:

输出fib(n)的值。

输入样例:

7

输出样例:

13

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码

/*@Keywords of Code:理解斐波那契数列
  @Author:毛毛maomaonwn
  @Date:2023/12/17 */

#include<stdio.h>


int main(){
    int n;
    scanf("%d",&n);

    printf("%d",fib(n));

    
    return 0;
}

int fib(int n){
    if(n==1){
        return 1;
    }
    else if(n==2){
        return 1;
    }
    else{
        return fib(n-1)+fib(n-2);
    }
}

7-4 求组合数 

1.题目

本题要求编写程序,根据公式Cnm​=m!(n−m)!n!​算出从n个不同元素中取出m个元素(m≤n)的组合数。

建议定义和调用函数fact(n)计算n!,其中n的类型是int,函数类型是double

输入格式:

输入在一行中给出两个正整数m和n(m≤n),以空格分隔。

输出格式:

按照格式“result = 组合数计算结果”输出。题目保证结果在double类型范围内。

输入样例:

2 7

输出样例:

result = 21

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码 

/*@Keywords of Code:理解阶乘
  @Author:毛毛maomaonwn
  @Date:2023/12/17 */


#include<stdio.h>

double fact(int n);

int main(){
    int m,n;
    double result;
    scanf("%d %d",&m,&n);

    
    result = fact(n)/fact(m)/fact(n-m);


    printf("result = %.0lf",result);
    
}

double fact(int n){
    double result = 1;                    //也满足0!的情况(0的阶乘为1)
    
    for(int i=1;i<=n;i++){
        result*=i;
    }

    return result;
}

7-5 求算式的和[1] 

1.题目

定义函数main(),输入正整数n,计算并输出下列算式的值。要求调用函数f(n)计算n*(n+1)…(2n-1),函数返回值类型是double。

输入格式:

输入在一行中给出一个正整数n。

输出格式:

在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后六位,请注意等号的左右各有一个空格。题目保证计算结果不超过双精度范围。

输入样例:

3

输出样例:

sum = 1.183333

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码 

/*@Keywords of Code:找到规律
  @Author:毛毛maomaonwn
  @Date:2023/12/19 */

#include<stdio.h>
double f(int n);


int main(){
    int n;
    double sum=0;              //局部变量如果没有初始化,默认值是随机值
    scanf("%d",&n);


    for(int i=1;i<=n;i++){     //i从1开始,因为算式是从1开始(1/f(1)=1)
        sum+=1/f(i);
    }
    
    printf("sum = %.6lf",sum);
}


double f(int n){
    double out = 1;
    for(int i=n;i<=2*n-1;i++){
        out*=i;
    }

    return out;
}

7-6 计算圆柱体的体积 

1.题目

输入圆柱的高和半径,求圆柱体积,volume=π×r2×h 。要求定义和调用函数cylinder (r, h )计算圆柱体的体积。

输入格式:

输入在一行中给出2个实数,分别为半径r和高h。

输出格式:

在一行中以“Volume = 值”的形式输出圆柱体的体积,结果保留三位小数。

输入样例:

3.0 10

输出样例:

Volume = 282.743

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码 

/*@Keywords of Code:函数基础知识
  @Author:毛毛maomaonwn
  @Date:2023/12/20 */

#include<stdio.h>
#define PI 3.1415926                       //如果最后的数值有偏差,可能是圆周率的位数不够多

double cylinder(double r,double h);

int main(){
    double r,h;
    scanf("%lf %lf",&r,&h);

    printf("Volume = %.3lf",cylinder(r,h));

    return 0;
}

double cylinder(double r,double h){
   return PI*r*r*h;
}

3.解析或补充

        1.使用#define定义常量

7-7 出生年 

1.题目

以上是新浪微博中一奇葩贴:“我出生于1988年,直到25岁才遇到4个数字都不相同的年份。”也就是说,直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求,自动填充“我出生于y年,直到x岁才遇到n个数字都不相同的年份”这句话。

输入格式:

输入在一行中给出出生年份y和目标年份中不同数字的个数n,其中y在[1, 3000]之间,n可以是2、或3、或4。注意不足4位的年份要在前面补零,例如公元1年被认为是0001年,有2个不同的数字0和1。

输出格式:

根据输入,输出x和能达到要求的年份。数字间以1个空格分隔,行首尾不得有多余空格。年份要按4位输出。注意:所谓“n个数字都不相同”是指不同的数字正好是n个。如“2013”被视为满足“4位数字都不同”的条件,但不被视为满足2位或3位数字不同的条件。

输入样例1:

1988 4

输出样例1:

25 2013

输入样例2:

1 2

输出样例2:

0 0001

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

2.参考代码 

/*@Keywords of Code:理解题目并耐心写出算法
  @Author:毛毛maomaonwn
  @Date:2023/12/20 */



//参考了网上的一个算法,这个太厉害了,清晰易懂,赞美大佬nwn



#include<stdio.h>

int main(){
    int n;
    int y;
    int i;
    int arr[10000];
    scanf("%d %d",&y,&n);


    
    for(i=y;i<10000;i++){         //不同数字的个数(n)据题目可知,只能为2,3,4(<10000)
        int flag=1;                      
        int save = i;
        
        for(int k=0;k<4;k++){
            arr[k]=save%10;
            save/=10;
        }

/*请注意题目上的说明:“所谓‘n个数字都不相同’是指不同的数字正好是n个。如'2013'被视为满足'4位数字都不同'的条件,但不被视为满足2位或3位数字不同的条件。”*/
    
        if(arr[0]!=arr[1] && arr[0]!=arr[2] && arr[0]!=arr[3]){  //第一个数的情况
            flag++;
        }
        if(arr[1]!=arr[2] && arr[1]!=arr[3]){                    //第二个数的情况
            flag++;
        } 
        if(arr[2]!=arr[3]){                                      //第三个数的情况
            flag++;
        }

        if(flag==n){
            break;
        }
    }

          printf("%d %04d",i-y,i);           //%04d:宽度为4,不足补0,超出时限制无效

      

    
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值