山东科技大学计算机学院2022级《程序设计基础(C语言)》期末考试题目和部分题解


用于记录山科的考试题目,供自己和学弟学妹学习复习使用。

总体难度和去年相仿,笔者机试只有80分,且只是大一,参考答案代码不规范多包涵。


Problem A: 简单计算二

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 671 Solved: 472

[Submit][Status]

Description

给定三个整数a、b、c,计算表达式a / (b + c)的值;其中“/”是浮点运算。

Input

输入为一行,包括三个数值较小整数a、b、c,且b + c不为零。

Output

输出一行,即表达式的计算结果,要求精确到小数点后3位。

Sample Input

1 1 3

Sample Output

0.250

HINT

#include <stdio.h>
int main()
{
    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    printf("%.3lf",(double)a/(double)(b+c));
}

Problem B: 奇偶求和

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 669 Solved: 416

[Submit][Status]

Description

输入若干整数,求其中所有奇数之和与所有偶数之和。

Input

输入只包含若干整数,至EOF结束。所有运算不会超过int存储范围。

Output

输出两个整数,分别是输入的所有奇数之和与所有偶数之和。

Sample Input

1 2 3 4 5

Sample Output

9 6

HINT

Append Code

#include <stdio.h>
int jishu(int x)
{
    if(x%2==0)return 0;
    return 1;
}
int main()
{
    int a=0,b=0,x;
    while(scanf("%d",&x)!=EOF)
    {
        if(jishu(x))
        {
            a+=x;
        }
        else b+=x;
 
    }
    printf("%d %d",a,b);
}

Problem C: 打印十字型

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 811 Solved: 339

[Submit][Status]

Description

从键盘输入一个整数n(1≤n≤10),打印出指定的十字图形。

Input

输入正整数n(1~10)。

Output

n阶十字型。

Sample Input

3

Sample Output

+

+

+++++

+

+

HINT

Append Code

#include <stdio.h>
  
int main()
{
    int n;
    scanf("%d",&n);
    int i,j,k;
    if(n==1)printf("+");
    else
    {
        for(i=1;i<=n-1;i++)
        {
            for(j=1;j<=n-1;j++)
            {
                printf(" ");
            }
            printf("+");
            for(j=1;j<=n-1;j++)
            {
                printf(" ");
            }
            printf("n");
        }
        for(i=1;i<=2*n-1;i++)
        {
      
            printf("+");
        }
        printf("n");
          for(i=1;i<=n-1;i++)
        {
            for(j=1;j<=n-1;j++)
            {
                printf(" ");
            }
            printf("+");
            for(j=1;j<=n-1;j++)
            {
                printf(" ");
            }
            if(i!=n-1)printf("n");
        }
    }
}

Problem D: 简单计算二(Append Code)

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 634 Solved: 419

[Submit][Status]

Description

给定三个整数a、b、c,计算表达式a / (b + c)的值;其中“/”是浮点运算。

-----------------------------------------------------------------------------

编写函数 f():

原型:void f(int a, int b, int c);

功能:根据题意完成计算和输出。

函数的调用格式见“Append Code”。

Input

输入为一行,包括三个数值较小整数a、b、c,且b + c不为零。

Output

输出一行,即表达式的计算结果,要求精确到小数点后3位。

Sample Input

1 1 3

Sample Output

0.250

HINT

Append Code

int main()

{

inta, b, c;

scanf("%d%d%d", &a, &b, &c);

f(a, b, c);

return0;

}

#include <stdio.h>
void f(int a, int b, int c)
{
    printf("%.3lf",(double)a/(double)(b+c));
}
 
int main()
{
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    f(a, b, c);
    return 0;
}

Problem E: 求数组中最大最小值(Append Code)

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 854 Solved: 290

[Submit][Status]

Description

给出若干整数,求其中的最大值和最小值。

-----------------------------------------------------------------------------

编写函数 max_min ():

原型:根据“Append Code”进行设计。

功能:把数组ar中的最大值和最小值找出来跟别存入max和min。

函数的调用格式见“Append Code”。

Input

首先输入一个整数n(n<100),然后输入n个整数。

Output

输出n个整数中的最小值和最大值。

Sample Input

5

1 2 3 4 5

Sample Output

1 5

HINT

Append Code

int main()

{

intmax, min, ar[100], i, n;

scanf("%d", &n);

for(i = 0; i < n; i++)

scanf("%d", &ar[i]);

max_min(&max, &min, ar, n);

printf("%d %dn", min, max);

return0;

}

#include <stdio.h>
void max_min(int*max,int*min,int*ar,int n)
{
    int i,j,k;
    *max=ar[0];
    *min=ar[0];
    for(i=1;i<n;i++)
    {
        if(ar[i]>*max)*max=ar[i];
        if(ar[i]<*min)*min=ar[i];
    }
}
 
int main()
{
    int max, min, ar[100], i, n;
    scanf("%d", &n);
    for(i = 0; i < n; i++)
        scanf("%d", &ar[i]);
    max_min(&max, &min, ar, n);
    printf("%d %dn", min, max);
    return 0;
}

Problem F: 字符串转日期(Append Code)

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 325 Solved: 183

[Submit][Status]

Description

对于用字符串存储的日期,把它的年月日提取出来转换成结构体形式。

-----------------------------------------------------------------------------

编写函数 to_date ():

原型:根据“Append Code”进行设计。

功能:把字符串s中年月日信息提取出来,并用结构体变量返回。

函数的调用格式见“Append Code”,完成结构体类型的定义。

Input

输入若干字符串,每个一行。每个字符串为一个合法的日期,其中前4位表示年份,中间两位表示月份,后2位表示日,位数不足会补0。

Output

按照年月日的顺序输出,两两用一个空格分开。

Sample Input

20011101

20220909

Sample Output

2001 11 1

2022 9 9

HINT

Append Code

int main()

{

charstr[10];

structdate dt;

while(gets(str) != NULL)

{

dt = to_date(str);

printf("%d %d %dn", dt.y, dt.m, dt.d);

}

return0;

}

#include <stdio.h>
struct date{
    int y;
    int m;
    int d;
};
struct date to_date(char str[])
{
    struct date dt;
    int a,b,c,d,e,f,g,h;
    a=str[0]-'0';
    b=str[1]-'0';
    c=str[2]-'0';
    d=str[3]-'0';
    e=str[4]-'0';
    f=str[5]-'0';
    g=str[6]-'0';
    h=str[7]-'0';
    dt.y=1000*a+100*b+10*c+d;
    dt.m=10*e+f;
    dt.d=10*g+h;
    return dt;
}
 
int main()
{
    char str[10];
    struct date dt;
    while(gets(str) != NULL)
    {
        dt = to_date(str);
        printf("%d %d %dn", dt.y, dt.m, dt.d);
    }
    return 0;
}

Problem G: 递归求斐波那契数

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 785 Solved: 21

[Submit][Status]

Description

斐波那契数列是1、2、3、5、8、13……。其中,每项是前两项之和。

现在请你用递归方法编程求斐波纳契数列第n项。

-----------------------------------------------------------------------------

Invalid Word(禁用单词)错误:在解决这个题目时,某些关键词是不允许被使用的。如果提交的程序中包含了下列的关键词之一,就会产生这个错误。

被禁用的关键字:for, while, do, break, continue, goto。

Input

输入一个整数n。

Output

输出斐波那契数列的第n项。

Sample Input

5

Sample Output

8

HINT

我知道好多人是这么写的,超时但容易想到的做法:

#include <stdio.h>
int f(int n)
{
    if(n==1)return 1;
    if(n==2)return 2;
    else return f(n-1)+f(n-2);
}
int main()
{
    int n;
    scanf("%d",&n);
    printf("%d",f(n));
    return 0;
}

我们应该用数组存放才可以不超时哦!!!

#include <stdio.h>
#include <string.h>
long long int arr[39999]={0,1,2,3};
long long int fib(int n) {
    if(n==0)return ;
    else if(arr[n]!=0)
    {
        return arr[n];
    }
    else
    {
        return arr[n]=fib(n-1)+fib(n-2);
    }
}
int main() {
    long long int n;
    scanf("%lld", &n);
    printf("%lld",fib(n));
    return 0;
}

Problem H: 与7无关的数

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 972 Solved: 231

[Submit][Status]

Description

一个整数如果每位数字不是7,同时既不是7的倍数,也不是7的平方、立方、四次方……。那么这个整数是与7无关的数

Input

输入若干int范围内的整数,至EOF结束。

Output

若是与7无关的数输出YES,否则输出NO。

Sample Input

7

21

49

58

73

101

Sample Output

NO

NO

NO

YES

NO

YES

HINT

#include <stdio.h>
int f(int x)
{
    while(x)
    {
        int a=x%10;
        if(a==7)return 0;
        x/=10;
    }
    return 1;
}
int main()
{
    int x;
    while(scanf("%d",&x)!=EOF)
    {
       if(f(x)&&x%7!=0)printf("YESn");
       else printf("NOn");
    }
    return 0;
}

Problem I: 十六进制转十进制

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 434 Solved: 252

[Submit][Status]

Description

十六进制是计算机中数据的一种表示方法,与十进制的对应关系是:十六进制的0~9对应十进制数值0-9,A~F对应十进制数值10-15。

现在你编写一个程序,完成一个十六进制数到十进制表示的转换。

Input

输入为多行,至EOF结束。每行为一个十六进制无符号整数n,n不超过int范围。n只包括数字0~9和大写字母A~F。

Output

输出有多行,每一行输出与输入相对应,是n的十进制。

Sample Input

11

FF

379A

Sample Output

1725514234

#include <stdio.h>
#include <string.h>
int main()
{
    char s[15];
    while(scanf("%s",s)!=EOF)
    {
        int num=0;
        int i,j,k;
        int len=strlen(s);
        int t=len;
        for(i=0;i<len;i++)
        {
            if(s[i]>='0'&&s[i]<='9')
            {
               int temp=s[i]-'0';
               for(j=1;j<=t-1;j++)
                temp*=16;
               num+=temp;
               t--;
 
            }
            else if(s[i]>='A'&&s[i]<='F')
            {
                int temp=s[i]-'A'+10;
                for(j=1;j<=t-1;j++)
                temp*=16;
               num+=temp;
               t--;
            }
        }
        printf("%dn",num);
    }
    return 0;
}

Problem J: 尼科梅彻斯定理

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 519 Solved: 255

[Submit][Status]

Description

任何一个正整数n的立方都可以唯一地写成n个相邻奇数之和。这就是尼科梅彻斯定理。例如,

13 = 1

23 = 8 = 3 + 5

33 = 27 = 7 + 9 + 11

43 = 64 = 13 + 15 + 17 + 19

现在你编程序计算n3是哪些相邻奇数之和。

Input

输入一个正整数n,且n<1291。

Output

输出为n个相邻整数,它们的和为n3。

Sample Input

5

Sample Output

21

23

25

27

29

#include <stdio.h>
int main()
{
    int n,a,b,i,j;
    scanf("%d",&n);
    int c=n*n-n+1;//这里需要找规律,这个题实际上是数学题
    for(i=c,j=0;j<n;j++,i+=2)
        printf("%dn",i);
    return 0;
}

Problem K: 求下一天

Time Limit: 1 Sec Memory Limit: 2 MB

Submit: 773 Solved: 36

[Submit][Status]

Description

给出一个日期,输出下一天的日期。

Input

输入若干日期至EOF结束,格式为y-m-d,其中y、m、d是三个正整数表示年月日,均为合法日期,其中y的输入范围是1000~9999年。

Output

输出每个日期下一天的日期。

Sample Input

2019-07-18

2022-01-01

2011-12-30

2033-11-30

Sample Output

2019-07-19

2022-01-02

2011-12-31

2033-12-01

目前不清楚为何这里Wrong Answer86%:

又重新布置了一遍这个题,这个题至今没找到问题在哪里,重新写了一个别的过了但是希望以后不经意的一个下午能找到这段代码的问题。(这里不留正确代码了哈哈希望学弟学妹帮我找找)

#include <stdio.h>
int leap(int x)
{
    if((x%4==0&&x&100!=0)||x%400==0)return 1;
    return 0;
}
int main()
{
    int days[13]={29,31,28,31,30,31,30,31,31,30,31,30,31};
    int y,m,d;
    while(scanf("%d-%d-%d",&y,&m,&d)!=EOF)
    {
        if(days[m]!=d&&m!=12&&m!=2)
        {
            if(m!=2)
            {
                printf("%04d-%02d-%02dn",y,m,d+1);
            }
 
        }
        else if(days[m]==d&&m!=12&&m!=2)
        {
            printf("%04d-%02d-01n",y,m+1);
        }
        else if(m==2)
        {
            if(leap(y))
            {
                if(days[0]!=d)
                {
                    printf("%04d-02-%02dn",y,d+1);
                }
                else if(days[0]==d)
                {
                    printf("%04d-03-01n",y);
                }
            }
            else if(!leap(y))
            {
                if(days[2]!=d)
                {
                    printf("%04d-02-%02dn",y,d+1);
                }
                else if(days[2]==d)
                {
                    printf("%04d-03-01n",y);
                }
            }
        }
        else if(m==12)
        {
            if(days[m]!=d)
            {
                printf("%04d-12-%02dn",y,d+1);
 
            }
            else if(days[m]==d)
            {
                printf("%04d-01-01n",y+1);
            }
        }
    }
    return 0;
}

Problem L: 查找单词

Time Limit: 1 Sec Memory Limit: 128 MB

Submit: 546 Solved: 20

[Submit][Status]

Description

给出n个英文单词,查找出其中正数或倒数第p个字符是c有哪些。

Input

输入分为两部分。

第一部分首先是一个整数n(n<=500),后接n个长度小于30的英文单词,这些单词均为小写字母组成。

第二部分是不超过100行,每行是一次查找,至EOF结束。每次查找的输入为一个英文字母c和一个整数p,用一个分隔开。若p为正,则在n个单词中查找左起第p个字符为c的所有单词;若p为负,则在n个单词中查找右起第p个字符为c的所有单词。

Output

输出为每次查找单词的结果,与输入的第二部分对应。每次查找的结果输出一行,若有多个单词符合查找条件,按照输入的顺序依次输出,两两单词间用一个空格分隔。若没有找到符合条件的单词,那么输出一个空行。

Sample Input

15

to

too

two

teem

tool

taste

tooth

be

bee

bed

box

bend

book

below

bench

t 1

e 2

o 3

h -1

e -2

b -3

Sample Output

to too two teem tool taste tooth

teem be bee bed bend below bench

too two tool tooth book

tooth bench

teem bee bed

bee bed box

HINT

#include <stdio.h>
#include <string.h>
 
#define MAX_N 500
#define MAX_L 30
 
char words[MAX_N][MAX_L + 1];
 
int main()
{
    int n;
    scanf("%d", &n);
 
    for (int i = 0; i < n; i++) {
        scanf("%s", words[i]);
    }
 
    char c;
    int p;
    while (scanf(" %c%d", &c, &p) == 2) {
        int count = 0;
        for (int i = 0; i < n; i++) {
            int len = strlen(words[i]);
            if (p > 0) {
                if (len >= p && words[i][p - 1] == c) {
                    printf("%s ", words[i]);
                    count++;
                }
            } else {
                if (len >= -p && words[i][len + p] == c) {
                    printf("%s ", words[i]);
                    count++;
                }
            }
        }
        if (count > 0) {
            printf("n");
        } else {
            printf("nn");
        }
    }
 
    return 0;
}

Problem M: 猴子选大王

Time Limit: 2 Sec Memory Limit: 16 MB

Submit: 4098 Solved: 2293

[Submit][Status]

Description

有一群进化程度很高的猴子,它们不再通过群殴产生猴王,而是采用一种非常文明的方法选出新的猴王。

假设猴群里有m只猴子,它们在篝火旁围坐成一个圈:某只猴子是1号,沿顺时针方向是2号、3号……m号,然后回到1号。由上一代猴王说出一个数字n,从1号猴子开始报数,报到n的猴子出局;再从刚出局猴子的下一个位置开始报数,报到n的猴子出局……如此重复,直至剩下一只猴子,它就成为新的猴王。

例如,当m=6、n=5时,依次出局的猴子序号是5、4、6、2、3,最后剩下1号是新猴王。

你来编写一个程序,模拟这个过程,算出第几号猴子会成为新的猴王。

Input

输入最多不超过100行,至EOF结束。每行一组数据,每组数据包含两个整数m和n(0<m,n<1000)。

Output

输出与输入对应,每行输出一个整数k(1<=k<=m),表示第k号猴子成为新的猴王。

Sample Input

6 5

8 3

1 5

2 3

Sample Output

1

7

1

2

HINT

#include<stdio.h>
int main()
{
    int n,m,i,j,k,a[1000];
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(i=0; i<n; i++)
        a[i]=i+1;        
        i=0;
        j=0;
        k=0;
        while(j<n-1)
        {

            if(a[i]!=0)
                k++;            
            if(k==m)
            {
                a[i]=0;
                j++;
                k=0;
            }
            i++;
            if(i==n)
                i=0;
        }
        for(i=0; i<n; i++)
            if(a[i]!=0)
                printf("%dn",a[i]);
    }

}