2020级C语言期末题目及解析
本文最后更新于 120 天前,其中的信息可能已经有所发展或是发生改变。
2020级C语言期末题目及解析

公式求值

  • 问题描述 已知公式Sn=a+aa+aaa+…+aa…a(n个a),其中a是一个数字(1≤a≤9),n表示a的位数(1≤n≤9),给出两个整数a和n,计算Sn,例如:a=2, n=5时Sn=2+22+222+2222+22222。
  • 输入说明 在一行上输入两个整数a和n的值,并以空格相隔,1≤a≤9,1≤n≤9。
  • 输出说明 输出Sn的计算结果。
  • 输入样例 2 5
  • 输出样例 24690
#include <stdio.h>

int main()
{
    int a, n, ans = 0;
    scanf("%d%d", &a, &n);
    int k = a;
    for (int i = 1; i <= n; i++)
    {
        ans += k;
        k = k * 10 + a;//往k的后面加一个a
    }
    printf("%d", ans);
}

进制转换

  • 问题描述 将十进制数转为其他进制数输出。
  • 输入说明 输入两个整数,分别表示十进制下的数字a(0≤a≤(2^31)-1)和进制N(2≤N≤9),整数之间使用空格分隔。
  • 输出说明 输出十进制数字a的N进制表示。
  • 输入样例 17 7
  • 输出样例 23
#include <stdio.h>

int main()
{
    int ans[10000], tot = 0, a, n;
    scanf("%d%d", &a, &n);
    while (a > 0) //使用短除法转换进制。因为短除法的结果需要倒序输出,所以用ans数组存下每步求余数的结果
    {
        ans[++tot] = a % n;
        a /= n;
    }
    for (int i = tot; i > 0; i--)
        printf("%d", ans[i]);
}

部分排序

  • 问题描述 给出n个整数,按指定顺序k进行排序,然后输出排序后的前m个整数。

  • 输入说明 输入的第一行有三个整数n、k和m(1 ≤ n ≤ 100,0≤ k ≤ 1,1 ≤ m ≤100),n表示正整数个数,k表示排序顺序(0表示从小到大排序,1表示从大到小排序),m表示要输出的整数个数,n、k和m之间用空格分隔。 输入的第二行有n个整数s1, s2, …, sn (-1000 ≤ si ≤ 10000, 1 ≤ i ≤ n)。相邻的整数用空格分隔。

  • 输出说明 在一行上输出按指定顺序排序后的前m个整数,整数之间用空格分隔。如果m>n,只输出n个整数。

  • 输入样例

    • 输入样例1 6 1 3 10 1 10 20 30 20
    • 输入样例2 5 0 3 10 1 8 12 7
  • 输出样例

    • 输出样例1 30 20 20
    • 输出样例2 1 7 8

代码1

#include <stdio.h>

int main()
{
    int n, k, m, a[110];
    scanf("%d%d%d", &n, &k, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    //选择排序
    for (int i = 1; i < n; i++)
        for (int j = i + 1; j <= n; j++)
            if (a[i] > a[j])
            {
                int t = a[i];
                a[i] = a[j];
                a[j] = t;
            }

    if (m > n) //根据题意,防止下标越界
        m = n;
    if (k == 0)
        for (int i = 1; i <= m; i++)
            printf("%d ", a[i]);
    else
        for (int i = n; i > n - m; i--)
            printf("%d ", a[i]);
}

选择排序动画示意图
代码2

#include <stdio.h>

int main()
{
    int n, k, m, a[110];
    scanf("%d%d%d", &n, &k, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    //冒泡排序
    for (int i = 1; i < n; i++)
        for (int j = 1; j <= n - i; j++)
            if (a[j] > a[j + 1])
            {
                int t = a[j];
                a[j] = a[j + 1];
                a[j + 1] = t;
            }

    if (m > n)
        m = n;
    if (k == 0)
        for (int i = 1; i <= m; i++)
            printf("%d ", a[i]);
    else
        for (int i = n; i > n - m; i--)
            printf("%d ", a[i]);
}

冒泡排序动画示意图
代码3

#include <algorithm>
#include <stdio.h>
//懒人福利
int main()
{
    int n, k, m, a[110];
    scanf("%d%d%d", &n, &k, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    std::sort(a + 1, a + n + 1); //调用algorithm库中的sort进行排序
    //如果数组元素是从下标0开始存储的,那就改成 std::sort(a,a+n);
    if (m > n)
        m = n;
    if (k == 0)
        for (int i = 1; i <= m; i++)
            printf("%d ", a[i]);
    else
        for (int i = n; i > n - m; i--)
            printf("%d ", a[i]);
}

上三角矩阵

  • 问题描述 主对角线(图中红色虚线)以下都是零的方阵称为上三角矩阵,如下图(a)是上三角矩阵,(b)不是上三角矩阵。给出一个n行n列的方阵,判断是不是上三角矩阵,如果是则求出上三角元素和,如果不是则统计下三角非零元素个数。

上三角矩阵示意图

  • 输入说明 输入第一行为一个整数n(1<n<50)表示方阵行数和列数;接下来是n行,每行n个整数,表示方阵的各个元素。

  • 输出说明 如果方阵是上三角矩阵,则输出上三角的元素和(不含主对角线上的元素),如果方阵不是上三角矩阵,则输出下三角中非零元素个数(不含主对角线上的元素)。

  • 输入样例

    • 输入样例1: 3 3 5 5 0 2 1 0 0 5
    • 输入样例2 3 3 2 6 1 0 4 0 2 1
  • 输出样例

    • 输出样例1 11
    • 输出样例2 2
#include <stdio.h>

int main()
{
    int n, sum = 0, cnt = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            int x;
            scanf("%d", &x);
            if (j > i) //如果是上三角范围内且不在主对角线上
                sum += x;
            else if (x != 0 && j < i) //如果在下三角范围内且不在主对角线上
                cnt++;
        }
    if (cnt > 0)
        printf("%d", cnt);
    else
        printf("%d", sum);
}

字符统计

  • 问题描述 输入一行长度不超过100的字符串,统计输出该字符串中字母,数字和其它字符的个数。
  • 输入说明 输入一行字符串。
  • 输出说明 输出该字符串中字母、数字和其它字符的个数,用空格分隔。
  • 输入样例 1983Birt ** sf))Zj\
  • 输出样例 8 4 7
#include <stdio.h>

int main()
{
    char c;
    int let = 0, num = 0, oth = 0;
    while (~scanf("%c", &c)) //当scanf读到东西时,该表达式值为true,否则为false。所以这句话意思是一直读入直到读不到东西
    {
        if (c >= '0' && c <= '9') //如果是数字
            num++;
        else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) //字母
            let++;
        else //都不是
            oth++;
    }
    printf("%d %d %d", let, num, oth);
}

子串统计

  • 问题描述 输入两个字符串,分别称为母串和子串。统计子串在母串中出现的次数和位置。注意子串可以重叠,见输入样例2。

  • 输入说明 输入分为两行,第一行为母串,第二行为子串。母串和子串的长度都不超过100。

  • 输出说明 输出子串在母串中出现的次数,并按出现次序输出每次子串在母串中出现时,子串第一个字符在母串中的位置(位置从0开始计算)。

  • 输入样例

    • 输入样例1: 12312431235412 123
    • 输入样例2: 12121212 1212
  • 输出样例

    • 输出样例1: 2 0 7
    • 输出样例2: 3 0 2 4
#include <stdio.h>
#include <string.h>

int main()
{
    char s1[100], s2[100];
    int ans[110], tot = 0;
    scanf("%s%s", s1, s2);
    for (int i = 0; i < strlen(s1) - strlen(s2); i++)
    {
        bool suc = 1;                        //假设从s1从i位置开始的长度和s2一样长的子串和s2一样
        for (int j = 0; j < strlen(s2); j++) //检验
            if (s2[j] != s1[i + j])
            {
                suc = 0; //若发现不一样,则假设不成立
                break;
            }
        if (suc)
            ans[++tot] = i;
    }
    printf("%d ", tot);
    for (int i = 1; i <= tot; i++)
        printf("%d ", ans[i]);
}

单词统计

  • 问题描述 输入3行字符,包含字母,空格和标点符号,统计其中有多少单词,单词之间用至少一个空格分隔开。
  • 输入说明 输入3行字符,每行字符数不超过100,包含字母、空格和标点符号,单词之间用至少一个空格分隔开。
  • 输出说明 输出统计出的单词数。
  • 输入样例 I like shopping. You are kind. It is a cat.
  • 输出样例 10
#include <stdio.h>
#include <string.h>

int main()
{
    char s1[100], s2[100], s3[100], ans = 0;
    
    gets(s1);
    gets(s2);
    gets(s3);

    for (int i = 0; s1[i] != '.'; i++) {
        if (s1[i] == ' ') {
            ans++;
        }
    }
    for (int i = 0; s2[i] != '.'; i++) {
        if (s2[i] == ' ') {
            ans++;
        }
    }
    for (int i = 0; s3[i] != '.'; i++) {
        if (s3[i] == ' ') {
            ans++;
        }
    }

    printf("%d", ans + 3);
    return 0;
}

矩阵元素筛选

  • 问题描述 请写一个程序,找出给定矩阵中的符合某个条件的某类元素,给出的条件为:该类元素在行上最小,在列上也最小。
  • 输入说明 输入数据由m+1行构成,第一行只有两个整数m和n(0<m<100,0<n<100),分别表示矩阵的行数和列数;接下来的m行、每行n个整数表示矩阵元素(矩阵中的元素互不相同),整数之间以空格间隔。
  • 输出说明 按行优先的顺序分行输出所有该类元素的行号、列号(行号和列号从0开始计数)及元素的值(用一个空格分隔),之后换行。
  • 输入样例 4 3 34 56 12 72 25 818 234 58 6 45 423 21
  • 输出样例 1 1 25 2 2 6
#include <stdio.h>

int a[110][110];

int main()
{
    int m, n;
    scanf("%d%d", &m, &n);
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            scanf("%d", &a[i][j]);

    for (int i = 0; i < m; i++)
    {
        //求这一行最小值
        int mn = 1 << 30, p;        //mn存储该行最小数字的值,p存储这个数字的列坐标。将mn初始化为一个很大的数   (mn=min)
        for (int j = 0; j < n; j++) //打擂台
            if (a[i][j] < mn)
                mn = a[i][j], p = j;

        bool suc = 1; //假设找到的这个数在这一列中也是最小的   (suc=success)
        for (int j = 0; j < m; j++)
            if (j != i && a[j][p] < a[i][p])
                suc = 0; //如果发现这一列中有比这个数更小的,那么假设不成立
        if (suc)  //如果假设成立,那么输出坐标和数值
        {
            printf("%d %d %d\n", i, p, a[i][p]);
        }
    }
}

 

螺旋方阵

  • 问题描述 螺旋方阵是指一个呈螺旋状的矩阵,它的左上角元素为1,由第一行开始按从左到右,从上到下,从从右向左,从下到上的顺序递增填充矩阵,直到矩阵填充完毕,下图所示是一个5*5阶的螺旋方阵。输入螺旋方阵的阶数N,按行输出该螺旋方阵。
    螺旋方阵示意图
  • 输入说明 输入一个正整数N(1<N<=100)。
  • 输出说明 逐行输出N阶螺旋方阵的元素,元素之间用空格分隔。
  • 输入样例 6
  • 输出样例 1 2 3 4 5 6 20 21 22 23 24 7 19 32 33 34 25 8 18 31 36 35 26 9 17 30 29 28 27 10 16 15 14 13 12 11

代码1

#include <stdio.h>
int a[110][110];
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}; 
//向量(dx[i],dy[i])表示下一步移动的方向,i=0:右,i=1:下,i=2:左,i=3:上
//(0,1)
//(1,0)
//(0,-1)
//(-1,0)
//(x,y)
int main()
{
    int n, k = 0, x = 1, y = 1;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            a[i][j] = -1; //在需要填数字的范围挖个坑
    for (int i = 1; i <= n * n; i++)
    {
        a[x][y] = i;                      //填写数字
        if (a[x + dx[k]][y + dy[k]] >= 0) //如果下一步走到了没挖坑的位置或者已经填上的位置
            k = (k + 1) % 4;              //那么切换到下一个方向(如果是3方向要换回0方向,所以对4求余数)
        x += dx[k], y += dy[k];           //走一步
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            printf("%d ", a[i][j]);
        puts("");
    }
}

代码2

#include <stdio.h>
int a[110][110];
int main()
{
	int n, j = 1;
	int x = 1, y = 0;

	scanf("%d", &n);

	for (int m = 1; m <= n; m++)
	{
		for (int l = 1; l <= n; l++)
		{
			a[m][l] = -1;
		}
	}

	for (int k = 1; k <= n * n; k++)
	{
		if (j % 4 == 1 && a[x][y + 1] == -1)
		{
			y++;
			a[x][y] = k;
		}
		else if (j % 4 == 2 && a[x + 1][y] == -1)
		{
			x++;
			a[x][y] = k;
		}
		else if (j % 4 == 2 && a[x][y - 1] == -1)
		{
			y--;
			a[x][y] = k;
		}
		else if (j % 4 == 0 && a[x - 1][y] == -1)
		{
			x--;
			a[x][y] = k;
		}
		else
		{
			j++;
			k--;
		}
	}
	for (int i1 = 1; i1 <= n; i1++)
	{
		for (int j1 = 1; j1 <= n; j1++)
			printf("%d ", a[i1][j1]);
		printf("\n");
	}
}

成绩统计

  • 问题描述 有N(0<N<=100)个学生,每个学生有3门课的成绩,输入每个学生数据(包括学号,姓名,三门课成绩),计算每个学生的平均成绩,并按照平均成绩从高到低的顺序输出学生信息,平均成绩相同时,则按照学号从小到大顺序输出。
  • 输入说明 第一行输入学生个数N,然后逐行输入N个学生信息,包括学号,姓名,三门课成绩,学号为正整数,姓名不超过10个字符,各门课程成绩为整数,用空格分隔。
  • 输出说明 按照平均成绩由高到低输出学生信息,平均成绩相同时,则按照学号从小到大顺序输出,输出信息包括学号、姓名、平均成绩(保留1位小数),用空格分隔,每个学生信息占一行。
  • 输入样例 6 18001 LiMing 88 45 90 18003 WangWei 66 60 68 18004 ZhangSan 77 90 83 18110 HanMeiMei 88 77 97 18122 SuSan 66 23 87 18008 YangYang 88 76 95
  • 输出样例 18110 HanMeiMei 87.3 18008 YangYang 86.3 18004 ZhangSan 83.3 18001 LiMing 74.3 18003 WangWei 64.7 18122 SuSan 58.7
#include <stdio.h>
#include <string.h>

struct student
{
    int id, a, b, c;
    float aver;
    char name[100];
} stu[110];

bool less(student x, student y) { return x.aver > y.aver || (x.aver == y.aver && x.id < y.id); }

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d %s %d %d %d", &stu[i].id, stu[i].name, &stu[i].a, &stu[i].b, &stu[i].c);
        stu[i].aver = (stu[i].a + stu[i].b + stu[i].c) / 3.0;
    }
    for (int i = 1; i < n; i++) //选择排序
        for (int j = i + 1; j <= n; j++)
            if (less(stu[j], stu[i]))
            {
                student t = stu[j];
                stu[j] = stu[i];
                stu[i] = t;
            }
    //或者 std::sort(stu + 1 , stu + n + 1 , less);
    for (int i = 1; i <= n; i++)
        printf("%d %s %.1f\n", stu[i].id, stu[i].name, stu[i].aver);
}

 

 

上一篇
下一篇