写在开头:

此文章仅供学习交流使用,我也是刚学c语言的菜鸟,代码写的一坨,请勿直接抄袭,请勿直接抄袭,请勿直接抄袭,大家共同进步!!!

做题网站传送门https://pintia.cn/

先修课-2024-1

7-1 最好的文档

有一位软件工程师说过一句很有道理的话:“Good code is its own best documentation.”(好代码本身就是最好的文档)。本题就请你直接在屏幕上输出这句话。

输入格式:

本题没有输入。

输出格式:

在一行中输出 Good code is its own best documentation.

#include <stdio.h>
int main()
{
    printf("Good code is its own best documentation.\n");
    return 0;
}

7-2 自动编程

输出语句是每个程序员首先要掌握的语句。Python 的输出语句很简单,只要写一个 print(X) 即可,其中 X 是需要输出的内容。

本题就请你写一个自动编程机,对任何一个要输出的整数 N,给出输出这个整数的 Python 语句。

输入格式:

输入给出一个不超过 105 的正整数。

输出格式:

在一行中打印输出这个整数的 Python 语句,其中不包含任何空格。

#include <stdio.h>
int main()
{
    int n;
    scanf("%d", &n);
    printf("print(%d)", n);
    return 0;
}

7-3 什么是机器学习

什么是机器学习?上图展示了一段面试官与“机器学习程序”的对话:

面试官:9 + 10 等于多少?
答:3
面试官:差远了,是19。
答:16
面试官:错了,是19。
答:18
面试官:不,是19。
答:19

本题就请你模仿这个“机器学习程序”的行为。

输入格式:

输入在一行中给出两个整数,绝对值都不超过 100,中间用一个空格分开,分别表示面试官给出的两个数字 A 和 B。

输出格式:

要求你输出 4 行,每行一个数字。第 1 行比正确结果少 16,第 2 行少 3,第 3 行少 1,最后一行才输出 A+B 的正确结果。

#include <stdio.h>
int main()
{
    int a;
    int b;
    int sum;
    scanf("%d %d", &a, &b);
    sum = a + b;
    printf("%d\n", sum - 16);
    printf("%d\n", sum - 3);
    printf("%d\n", sum - 1);
    printf("%d\n", sum);
    return 0;
}

先修课-2024-2

7-1 是不是太胖了

据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。已知市斤的数值是公斤数值的两倍。现给定某人身高,请你计算其标准体重应该是多少?(顺便也悄悄给自己算一下吧……)

输入格式:

输入第一行给出一个正整数H(100 < H ≤ 300),为某人身高。

输出格式:

在一行中输出对应的标准体重,单位为市斤,保留小数点后1位。

#include <stdio.h>
int main()
{
    int height;
    double weight_kg, weight_jin;
    scanf("%d", &height);
    weight_kg = (height - 100) * 0.9;
    weight_jin = weight_kg * 2;
    printf("%.1lf\n", weight_jin);
    return 0;
}

7-2 计算存款利息

本题目要求计算存款利息,计算公式为interest=money×(1+rate)yearmoney,其中interest为存款到期时的利息(税前),money是存款金额,year是存期,rate是年利率。

输入格式:

输入在一行中顺序给出三个正实数moneyyearrate,以空格分隔。

输出格式:

在一行中按“interest = 利息”的格式输出,其中利息保留两位小数。

#include <stdio.h>
#include <math.h>
int main()
{
    double money, rate, interest, year;
    scanf("%lf %lf %lf", &money, &year, &rate);
    interest = money * pow(1 + rate, year) - money;
    printf("interest = %.2lf\n", interest);
    return 0;
}

7-3 计算摄氏温度

给定一个华氏温度F,本题要求编写程序,计算对应的摄氏温度C。计算公式:C=5×(F−32)/9。题目保证输入与输出均在整型范围内。

输入格式:

输入在一行中给出一个华氏温度。

输出格式:

在一行中按照格式“Celsius = C”输出对应的摄氏温度C的整数值。

#include <stdio.h>
int main()
{
    int fahrenheit, celsius;
    scanf("%d", &fahrenheit);
    celsius = 5 * (fahrenheit - 32) / 9;
    printf("Celsius = %d\n", celsius);
    return 0;
}

先修课-2024-3

7-1 程序员买包子

这是一条检测真正程序员的段子:假如你被家人要求下班顺路买十只包子,如果看到卖西瓜的,买一只。那么你会在什么情况下只买一只包子回家?
本题要求你考虑这个段子的通用版:假如你被要求下班顺路买 N 只包子,如果看到卖 X 的,买 M 只。那么如果你最后买了 K 只包子回家,说明你看到卖 X 的没有呢?

输入格式:

输入在一行中顺序给出题面中的 NXMK,以空格分隔。其中 NMK 为不超过 1000 的正整数,X 是一个长度不超过 10 的、仅由小写英文字母组成的字符串。题目保证 N=M

输出格式:

在一行中输出结论,格式为:

  • 如果 K=N,输出 mei you mai X de
  • 如果 K=M,输出 kan dao le mai X de
  • 否则输出 wang le zhao mai X de.
    其中 X 是输入中给定的字符串 X
#include <stdio.h>
int main()
{
    int N, M, K;
    char X[11];
    scanf("%d %s %d %d", &N, X, &M, &K);
    if (K == N)
    {
        printf("mei you mai %s de\n", X);
    }
    else if (K == M)
    {
        printf("kan dao le mai %s de\n", X);
    }
    else
    {
        printf("wang le zhao mai %s de\n", X);
    }
    return 0;
}

7-2 新胖子公式

根据钱江晚报官方微博的报导,最新的肥胖计算方法为:体重(kg) / 身高(m) 的平方。如果超过 25,你就是胖子。于是本题就请你编写程序自动判断一个人到底算不算胖子。

输入格式:

输入在一行中给出两个正数,依次为一个人的体重(以 kg 为单位)和身高(以 m 为单位),其间以空格分隔。其中体重不超过 1000 kg,身高不超过 3.0 m。

输出格式:

首先输出将该人的体重和身高代入肥胖公式的计算结果,保留小数点后 1 位。如果这个数值大于 25,就在第二行输出 PANG,否则输出 Hai Xing

#include <stdio.h>
int main()
{
    double weight, height, bmi;
    scanf("%lf %lf", &weight, &height);
    bmi = weight / (height * height);
    printf("%.1lf\n", bmi);
    if (bmi > 25.0)
    {
        printf("PANG\n");
    }
    else
    {
        printf("Hai Xing\n");
    }
    return 0;
}

7-3 真的恭喜你

当别人告诉你自己考了 x 分的时候,你要回答说:“恭喜你考了 x 分!”比如小明告诉你他考了90分,你就用汉语拼音打出来 gong xi ni kao le 90 fen!

但是如果小明没考好,比如只考了 20 分,你也“恭喜”人家就不对了。这时候你应该安慰他说:“考了 20 分别泄气!”用汉语拼音写出来就是 kao le 20 fen bie xie qi!

输入格式:

输入在一行里给出一位小朋友的分数。这个分数是一个 0 到 100 之间的整数。

输出格式:

在一行中输出你对这位小朋友说的话。如果人家考到不低于 90 分,就说 gong xi ni kao le X fen!;如果不到 90 分,就说 kao le X fen bie xie qi!。其中 X 是小朋友输入的分数。

#include <stdio.h>
int main()
{
    int score;
    scanf("%d", &score);
    if (score >= 90)
    {
        printf("gong xi ni kao le %d fen!\n", score);
    }
    else
    {
        printf("kao le %d fen bie xie qi!\n", score);
    }
    return 0;
}

7-4 判断一个三位数是否为水仙花数

本题要求编写程序,判断一个给定的三位数是否为水仙花数。三位水仙花数,即其个位、十位、百位数字的立方和等于该数本身。

输入格式:

输入在一行中给出一个需要判断的整数 N(100≤N≤999)。

输出格式:

如果N是水仙花数,则在一行中输出Yes,否则输出No。如果N不是三位数,则输出Invalid Value.

#include <stdio.h>
int main()
{
    int N;
    scanf("%d", &N);
    if (N < 100 || N > 999)
    {
        printf("Invalid Value.\n");
    }
    else
    {
        int units, tens, hundreds;
        hundreds = N / 100;
        tens = (N / 10) % 10;
        units = N % 10;
        int sum = hundreds * hundreds * hundreds + tens * tens * tens + units * units * units;
        if (sum == N)
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
    return 0;
}

7-5 成绩转换

本题要求编写程序将一个百分制成绩转换为五分制成绩。转换规则:

  • 大于等于90分为A;
  • 小于90且大于等于80为B;
  • 小于80且大于等于70为C;
  • 小于70且大于等于60为D;
  • 小于60为E。

输入格式:

输入在一行中给出一个整数的百分制成绩。

输出格式:

在一行中输出对应的五分制成绩。

#include <stdio.h>
int main()
{
    int score;
    char grade;
    scanf("%d", &score);
    if (score >= 90)
    {
        grade = 'A';
    }
    else if (score >= 80)
    {
        grade = 'B';
    }
    else if (score >= 70)
    {
        grade = 'C';
    }
    else if (score >= 60)
    {
        grade = 'D';
    }
    else
    {
        grade = 'E';
    }
    printf("%c\n", grade);
    return 0;
}

7-6 五级制成绩

任务描述

五级制成绩表示法可以这样来理解,A代表[90-100]、B代表[80-90)、C代表[70-80)、D代表[60-70)、E代表[0-60)。
给出五级制成绩(一个字符),请输出这个字符所代表的分数范围。

输入格式:

一个大写的英文字符,代表五级制成绩。

输出格式:

在一行中输出该成绩所表示的整数成绩范围区间,如果该字符不在五级制定义范围之内,输出:ERROR。

#include <stdio.h>
int main() {
    char grade;
    scanf("%c", &grade);
    switch(grade) {
        case 'A':
            printf("[90-100]\n");
            break;
        case 'B':
            printf("[80-90)\n");
            break;
        case 'C':
            printf("[70-80)\n");
            break;
        case 'D':
            printf("[60-70)\n");
            break;
        case 'E':
            printf("[0-60)\n");
            break;
        default:
            printf("ERROR\n");
            break;
    }
    return 0;
}

7-7 输出星期名

请编写程序,输入星期数,输出对应的英文星期名。

星期数 星期名
0 Sunday
1 Monday
2 Tuesday
3 Wednesday
4 Thursday
5 Friday
6 Saturday

输入格式

w

输出格式

若 w 在 0 ~ 6 范围内,则输出星期名 若 w 在 0 ~ 6 范围外,则输出None

#include <stdio.h>
int main() {
    int w;
    scanf("%d", &w);
    switch (w) {
        case 0:
            printf("Sunday\n");
            break;
        case 1:
            printf("Monday\n");
            break;
        case 2:
            printf("Tuesday\n");
            break;
        case 3:
            printf("Wednesday\n");
            break;
        case 4:
            printf("Thursday\n");
            break;
        case 5:
            printf("Friday\n");
            break;
        case 6:
            printf("Saturday\n");
            break;
        default:
            printf("None\n");
            break;
    }
    return 0;
}

先修课-2024-4

7-1 电子汪

据说汪星人的智商能达到人类 4 岁儿童的水平,更有些聪明汪会做加法计算。比如你在地上放两堆小球,分别有 1 只球和 2 只球,聪明汪就会用“汪!汪!汪!”表示 1 加 2 的结果是 3。

本题要求你为电子宠物汪做一个模拟程序,根据电子眼识别出的两堆小球的个数,计算出和,并且用汪星人的叫声给出答案。

输入格式:

输入在一行中给出两个 [1, 9] 区间内的正整数 A 和 B,用空格分隔。

输出格式:

在一行中输出 A + B 个Wang!

#include <stdio.h>
int main()
{
    int A, B;
    scanf("%d %d", &A, &B);
    for (int i=0;i < A+B; i++){
        printf("Wang!");
    }
    return 0;
}

7-2 爬动的蠕虫

一条蠕虫长1寸,在一口深为N寸的井的底部。已知蠕虫每1分钟可以向上爬U寸,但必须休息1分钟才能接着往上爬。在休息的过程中,蠕虫又下滑了D寸。就这样,上爬和下滑重复进行。请问,蠕虫需要多长时间才能爬出井?

这里要求不足1分钟按1分钟计,并且假定只要在某次上爬过程中蠕虫的头部到达了井的顶部,那么蠕虫就完成任务了。初始时,蠕虫是趴在井底的(即高度为0)。

输入格式:

输入在一行中顺序给出3个正整数N、U、D,其中D<U,N不超过100。

输出格式:

在一行中输出蠕虫爬出井的时间,以分钟为单位。

#include <stdio.h>
int main() {
    int N, U, D;
    
    // 输入井的深度N,上爬距离U,下滑距离D
    scanf("%d %d %d", &N, &U, &D);
    
    int height = 0; // 蠕虫当前高度
    int time = 0;   // 时间
    
    while (1) {
        time++;      // 每次上爬前时间加1分钟
        height += U; // 蠕虫上爬U寸
        
        if (height >= N) {
            // 如果蠕虫爬出了井,结束循环
            break;
        }
        
        time++;      // 蠕虫休息1分钟
        height -= D; // 蠕虫下滑D寸
    }
    
    // 输出蠕虫爬出井的时间
    printf("%d\n", time);
    
    return 0;
}

7-3 约分最简分式

分数可以表示为分子/分母的形式。编写一个程序,要求用户输入一个分数,然后将其约分为最简分式。最简分式是指分子和分母不具有可以约分的成分了。如6/12可以被约分为1/2。当分子大于分母时,不需要表达为整数又分数的形式,即11/8还是11/8;而当分子分母相等时,仍然表达为1/1的分数形式。

输入格式:

输入在一行中给出一个分数,分子和分母中间以斜杠/分隔,如:12/34表示34分之12。分子和分母都是正整数(不包含0,如果不清楚正整数的定义的话)。

提示:

  • 对于C语言,在scanf的格式字符串中加入/,让scanf来处理这个斜杠。
  • 对于Python语言,用a,b=map(int, input().split('/'))这样的代码来处理这个斜杠。

输出格式:

在一行中输出这个分数对应的最简分式,格式与输入的相同,即采用分子/分母的形式表示分数。如
5/6表示6分之5。

#include <stdio.h>
int main()
{
	int i;
	int fz, fm;
	scanf("%d/%d", &fz, &fm);
	for (i = fm; i >= 2; i--)
	{
		if (fm % i == 0 && fz % i == 0)
		{
			fz = fz / i;
			fm = fm / i;
		}
	}
	printf("%d/%d", fz, fm);
	return 0;
}

7-4 寻找250

对方不想和你说话,并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。

输入格式:

输入在一行中给出不知道多少个绝对值不超过1000的整数,其中保证至少存在一个“250”。

输出格式:

在一行中输出第一次出现的“250”是对方扔过来的第几个数字(计数从1开始)。题目保证输出的数字在整型范围内。

#include <stdio.h>
int main()
{
    int a,i;
    i=0;
    while(1)
    {
        scanf("%d",&a);
        if(a==250)	break;
        i++;
    }
    printf("%d\n",i+1);
    return 0;
}

7-5 降价提醒机器人

小 T 想买一个玩具很久了,但价格有些高,他打算等便宜些再买。但天天盯着购物网站很麻烦,请你帮小 T 写一个降价提醒机器人,当玩具的当前价格比他设定的价格便宜时发出提醒。

输入格式:

输入第一行是两个正整数 NM (1≤N≤100,0≤M≤1000),表示有 N 条价格记录,小 T 设置的价格为 M

接下来 N 行,每行有一个实数 Pi​(−1000.0<Pi​<1000.0),表示一条价格记录。

输出格式:

对每一条比设定价格 M 便宜的价格记录 P,在一行中输出 On Sale! P,其中 P 输出到小数点后 1 位。

#include <stdio.h>
int main()
{
    int M,N,i=0;
    double p;
    scanf("%d %d",&N,&M);
    while(i<N){
        i++;
        scanf("%lf",&p);
        if(p<M)
            printf("On Sale! %.1f\n",p);
    }
    return 0;
}

7-6 求特殊方程的正整数解

本题要求对任意给定的正整数N,求方程X2+Y2=N的全部正整数解。

输入格式:

输入在一行中给出正整数N(≤10000)。

输出格式:

输出方程X2+Y2=N的全部正整数解,其中XY。每组解占1行,两数字间以1空格分隔,按X的递增顺序输出。如果没有解,则输出No Solution

#include <stdio.h>
int main()
{
    int N;
    int i, j, m = 0;
    scanf("%d", &N);
    for (j = 1; j <= 100; j++)
    {
        for (i = 1; i <= 100; i++)
            if ((i * i + j * j == N) && (j < i))
            {
                printf("%d %d\n", j, i);
                ++m;
            }
    }
    if (m == 0)
        printf("No Solution");
}

7-7 计算阶乘和

对于给定的正整数N,需要你计算 S=1!+2!+3!+...+N!。

输入格式:

输入在一行中给出一个不超过10的正整数N

输出格式:

在一行中输出S的值。

#include <stdio.h>
int main()
{
    int N;
    int i;
    int s = 1, S = 0;
    scanf("%d", &N);
    for (i = 1; i <= N; i++)
    {
        s = s * i;
        S = S + s;
    }
    printf("%d", S);
}

先修课-2024-5

7-1 大笨钟的心情

有网友问:未来还会有更多大笨钟题吗?笨钟回复说:看心情……

本题就请你替大笨钟写一个程序,根据心情自动输出回答。

输入格式:

输入在一行中给出 24 个 [0, 100] 区间内的整数,依次代表大笨钟在一天 24 小时中,每个小时的心情指数。

随后若干行,每行给出一个 [0, 23] 之间的整数,代表网友询问笨钟这个问题的时间点。当出现非法的时间点时,表示输入结束,这个非法输入不要处理。题目保证至少有 1 次询问。

输出格式:

对每一次提问,如果当时笨钟的心情指数大于 50,就在一行中输出 心情指数 Yes,否则输出 心情指数 No

#include <stdio.h>
int arr[24];
int main()
{
    int time;
    for (int i = 0; i < 24; i++)
    {
        scanf("%d", &arr[i]);
    }
    scanf("%d", &time);
    while (time >= 0 && time <= 23)
    {
        if (arr[time] > 50)
        {
            printf("%d Yes\n", arr[time]);
        }
        else
        {
            printf("%d No\n", arr[time]);
        }
        scanf("%d", &time);
    }
    return 0;
}

7-2 求最大值及其下标

本题要求编写程序,找出给定的n个数中的最大值及其对应的最小下标(下标从0开始)。

输入格式:

输入在第一行中给出一个正整数n(1<n≤10)。第二行输入n个整数,用空格分开。

输出格式:

在一行中输出最大值及最大值的最小下标,中间用一个空格分开。

#include <stdio.h>
int main()
{
    int n, num, max_index, max_num = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &num);
        if (num > max_num)
        {
            max_num = num;
            max_index = i;
        }
    }
    printf("%d %d", max_num, max_index);
}

7-3 统计分数段人数

请对某次考试的分数,统计各分数段人数,统计原则:分别对10分以下、10-19分、20-29分、30-39分、40-49分、50-59分、60-69分、70-79,80-89分,90到99分,100分为一段,共11段 。
注意:如果输入分数不在[0,100]之间,不参与统计。

输入格式:

先输入一个整数n,表示将输入n个分数。
再输入n个分数,范围在[0~100].
每个数用空格间隔。

输出格式:

每一行输出一个分数段的人数统计结果。分数段用0~10表示。

#include <stdio.h>
int main()
{
    int n;
    int score, count[11] = {0};
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &score);
        if (score >= 0 & score <= 100)
        {
            count[score / 10]++;
        }
    }
    for (int i = 0; i <= 10; i++)
    {
        printf("%d: %d\n", i, count[i]);
    }
    return 0;
}

7-4 C程序设计教程与实训-数组-查找k出现次数

从键盘输入10个整数,将其存入数组中,输入一个整数k,在数组中查找k出现的次数。

输入格式:

在第一行输入10个整数(在int类型的范围内),在第二行输入要查找的整数k。

输出格式:

k出现的次数。如果未出现,输出0。

#include <stdio.h>
int arr[10];
int main()
{
    int key, cnt = 0;
    for (int i = 0; i < 10; i++)
    {
        scanf("%d", &arr[i]);
    }
    scanf("%d", &key);
    for (int i = 0; i < 10; i++)
    {
        if (arr[i] == key)
        {
            cnt += 1;
        }
    }
    printf("%d", cnt);
    return 0;
}

7-5 求矩阵的局部极大值

给定MN列的整数矩阵A,如果A的非边界元素A[i][j]大于相邻的上下左右4个元素,那么就称元素A[i][j]是矩阵的局部极大值。本题要求给定矩阵的全部局部极大值及其所在的位置。

输入格式:

输入在第一行中给出矩阵A的行数M和列数N(3≤M,N≤20);最后M行,每行给出A在该行的N个元素的值。数字间以空格分隔。

输出格式:

每行按照“元素值 行号 列号”的格式输出一个局部极大值,其中行、列编号从1开始。要求按照行号递增输出;若同行有超过1个局部极大值,则该行按列号递增输出。若没有局部极大值,则输出“None 总行数 总列数”。

#include <stdio.h>
int main()
{
    int m, n, cnt = 0;
    scanf("%d %d", &m, &n);
    int a[m][n];
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    for (int i = 1; i < m - 1; i++)
    {
        for (int j = 1; j < n - 1; j++)
        {
            if (a[i][j] > a[i - 1][j] && a[i][j] > a[i + 1][j] && a[i][j] > a[i][j - 1] && a[i][j] > a[i][j + 1])
            {
                printf("%d %d %d\n", a[i][j], i + 1, j + 1);
                cnt++;
            }
        }
    }
    if (cnt == 0)
    {
        printf("None %d %d\n", m, n);
        return 0;
    }
}

7-6 打印杨辉三角

本题要求按照规定格式打印前N行杨辉三角。

输入格式:

输入在一行中给出N(1≤N≤10)。

输出格式:

以正三角形的格式输出前N行杨辉三角。每个数字占固定4位。

#include <stdio.h>
int main()
{
    int n;
    int triangle[10][10];
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j <= i; j++)
        {
            if (j == 0 || j == i)
                triangle[i][j] = 1;
            else
                triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int k = 0; k < n - i - 1; k++)
        {
            printf(" ");
        }
        for (int j = 0; j <= i; j++)
        {
            if (triangle[i][j] < 10)
            {
                printf("   %d", triangle[i][j]);
            }
            else if (triangle[i][j] < 100)
            {
                printf("  %d", triangle[i][j]);
            }
            else
            {
                printf(" %d", triangle[i][j]);
            }
        }
        printf("\n");
    }
    return 0;
}

先修课-2024-6

6-1 使用函数输出一个整数的逆序数

本题要求实现一个求整数的逆序数的简单函数。

函数接口定义:

int reverse( int number );

其中函数reverse须返回用户传入的整型number的逆序数。

裁判测试程序样例:

#include <stdio.h>
int reverse( int number );
int main()
{
    int n;
    scanf("%d", &n);
    printf("%d\n", reverse(n));
    return 0;
}
/* 你的代码将被嵌在这里 */
int reverse(int number)
{
    int re_num = 0;
    int a = number;
    if (number < 0)
    {
        a *= -1;
    }
    while (a > 0)
    {
        re_num = re_num * 10 + a % 10;
        a /= 10;
    }
    if (number < 0)
    {
        re_num *= -1;
    }
    return re_num;
}

6-2 使用函数求最大公约数

本题要求实现一个计算两个数的最大公约数的简单函数。

函数接口定义:

int gcd( int x, int y );

其中xy是两个正整数,函数gcd应返回这两个数的最大公约数。

裁判测试程序样例:

#include <stdio.h>
int gcd( int x, int y );
int main()
{
    int x, y;
    
    scanf("%d %d", &x, &y);
    printf("%d\n", gcd(x, y));
    
    return 0;
}
/* 你的代码将被嵌在这里 */
// 求两数最大公约数,三种方法
// 遍历法
int gcd(int x, int y)
{
    int a = (x < y) ? x : y; // 三目运算符找最小值
    while ((x % a != 0) || (y % a != 0))
    {
        a--;
    }
    return a;
}
// 更相减损法
int gcd(int x, int y)
{
    while (x != y)
    {
        if (x > y)
            x = x - y;
        if (x < y)
            y = y - x;
    }
    return x;
}
// 辗转相除法
int gcd(int x, int y)
{
    int c = x % y;
    while (c)
    {
        x = y;
        y = c;
        c = x % y;
    }
    return y;
}

6-3 使用函数的选择法排序

本题要求实现一个用选择法对整数数组进行简单排序的函数。

函数接口定义:

void sort( int a[], int n );

其中a是待排序的数组,n是数组a中元素的个数。该函数用选择法将数组a中的元素按升序排列,结果仍然在数组a中。

裁判测试程序样例:

#include <stdio.h>
#define MAXN 10
void sort( int a[], int n );
int main()
{
    int i, n;
    int a[MAXN];
    
    scanf("%d", &n);
    for( i=0; i<n; i++ )
        scanf("%d", &a[i]);
    sort(a, n);
    printf("After sorted the array is:");
    for( i = 0; i < n; i++ )
        printf(" %d", a[i]);
    printf("\n");
        
    return 0;
}
/* 你的代码将被嵌在这里 */
// 选择排序
void sort(int a[], int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        // 假设当前未排序部分的第一个元素是最小值
        int min = i;
        // 在未排序部分寻找最小值
        for (int j = i + 1; j < n; j++)
        {
            if (a[j] < a[min])
            {
                min = j; // 更新最小值的索引
            }
        }
        // 如果找到的最小值的索引不是当前i,则交换
        if (min != i)
        {
            int temp = a[i];
            a[i] = a[min];
            a[min] = temp;
        }
    }
}

6-4 求排列数

本题要求实现一个计算阶乘的简单函数,使得可以利用该函数,根据公式Pnm​=(nm)!/n!​算出从n个不同元素中取出m个元素(0<mn)的排列数。

函数接口定义:

double fact( int n );

其中n是用户传入的参数,函数返回n的阶乘。

裁判测试程序样例:

#include <stdio.h>
double fact( int n );
int main(void)
{    
    int m, n;
    double result; 
    scanf("%d%d", &m, &n);
    if(m > 0 && n > 0 && m <= n){
        result = fact(n)/fact(n-m);
        printf("result = %.0f\n", result);    
    }
    return 0;
}
/* 请在这里填写答案 */
// 计算阶乘
double fact(int n)
{
    double result = 1.0;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
    return result;
}

先修课-2024-7

程序填空题

PTA没有判我对错,故不给出答案

函数题

6-1 计算两数的和与差

本题要求实现一个计算输入的两数的和与差的简单函数。

函数接口定义:

void sum_diff( float op1, float op2, float *psum, float *pdiff );

其中op1op2是输入的两个实数,*psum*pdiff是计算得出的和与差。

裁判测试程序样例:

#include <stdio.h>
void sum_diff( float op1, float op2, float *psum, float *pdiff );
int main()
{
    float a, b, sum, diff;
    scanf("%f %f", &a, &b);
    sum_diff(a, b, &sum, &diff);
    printf("The sum is %.2f\nThe diff is %.2f\n", sum, diff);
    
    return 0; 
}
/* 你的代码将被嵌在这里 */
void sum_diff(float op1, float op2, float *psum, float *pdiff){
    *psum = op1 + op2;
    *pdiff = op1 - op2; 
}

6-2 拆分实数的整数与小数部分

本题要求实现一个拆分实数的整数与小数部分的简单函数。

函数接口定义:

void splitfloat( float x, int *intpart, float *fracpart );

其中x是被拆分的实数(0≤x<10000),*intpart*fracpart分别是将实数x拆分出来的整数部分与小数部分。

裁判测试程序样例:

#include <stdio.h>
void splitfloat( float x, int *intpart, float *fracpart );
int main()
{
    float x, fracpart;
    int intpart;
    
    scanf("%f", &x);
    splitfloat(x, &intpart, &fracpart);
    printf("The integer part is %d\n", intpart);
    printf("The fractional part is %g\n", fracpart);
    
    return 0;
}
/* 你的代码将被嵌在这里 */
void splitfloat(float x, int *intpart, float *fracpart)
{
    *intpart = (int)x;
    *fracpart = x - *intpart;
}

6-3 使用函数找出数组中的最大值

本题要求实现一个找出整型数组中最大值的函数。

函数接口定义:

int FindArrayMax( int a[], int n );

其中a是用户传入的数组,n是数组a中元素的个数。函数返回数组a中的最大值。

裁判测试程序样例:

#include <stdio.h>
#define MAXN 10
int FindArrayMax( int a[], int n );
int main()
{
    int i, n;
    int a[MAXN];
    
    scanf("%d", &n);
    for( i=0; i<n; i++ ){
        scanf("%d", &a[i]);
    }
    printf("%d\n", FindArrayMax(a, n));
   
    return 0;
}
/* 请在这里填写答案 */
int FindArrayMax(int a[], int n)
{
    int max = a[0];
    for (int i = 0; i < n; i++)
        if (a[i] > max)
            max = a[i];
    return max;
}

编程题

7-1 动态内存中数据排序

任务描述:

读入整数N,再读入N个整数,将这N个整数从小到大排序后输出。(不能定义整型数组,用动态内存技术实现)

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int N;
    scanf("%d", &N);
    int *arr = (int *)malloc(N * sizeof(int));
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &arr[i]);
    }
    // 冒泡排序
    for (int i = 0; i < 5; i++)
        for (int j = 0; j < 5 - 1 - i; j++)
            if (arr[j] > arr[j + 1]) // 升序
            {
                int temp;
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
    for (int i = 0; i < N; i++)
    {
        if (i > 0)
            printf(" ");
        printf("%d", arr[i]);
    }
    free(arr);
    return 0;
}

7-2 动态数组(需要多大内存申请多大内存)

任务描述:

输入整数N,再输入N个整数,将这N个整数倒序输出。(不用定义数组,用动态内存实现)

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int N;
    scanf("%d", &N);
    int *arr = (int *)malloc(N * sizeof(int));
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &arr[i]);
    }
    for (int i = N - 1; i >= 0; i--)
    {
        if (i != N - 1)
            printf(" ");
        printf("%d", arr[i]);
    }
    free(arr);
    return 0;
}

先修课-2024-8

程序填空题

PTA没有判我对错,故不给出答案

编程题

7-1 有理数均值

本题要求编写程序,计算N个有理数的平均值。

输入格式:

输入第一行给出正整数N(≤100);第二行中按照a1/b1 a2/b2 …的格式给出N个分数形式的有理数,其中分子和分母全是整形范围内的整数;如果是负数,则负号一定出现在最前面。

输出格式:

在一行中按照a/b的格式输出N个有理数的平均值。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。

#include <stdio.h>

// 辗转相除法求最大公约数
int gcd(int a, int b)
{
    if (b == 0)
    {
        return a;
    }
    return gcd(b, a % b);
}

int main()
{
    int N;
    scanf("%d", &N);
    int sum_a = 0, sum_b = 1;
    for (int i = 0; i < N; i++)
    {
        int a, b;
        scanf("%d/%d", &a, &b);
        sum_a = sum_a * b + a * sum_b;
        sum_b *= b;
        int g = gcd(abs(sum_a), sum_b);
        sum_a /= g;
        sum_b /= g;
    }
    sum_b *= N;
    int g = gcd(abs(sum_a), sum_b);
    sum_a /= g;
    sum_b /= g;
    if (sum_b == 1)
    {
        printf("%d\n", sum_a);
    }
    else
    {
        printf("%d/%d\n", sum_a, sum_b);
    }
    return 0;
}

7-2 找出总分最高的学生

给定N个学生的基本信息,包括学号(由5个数字组成的字符串)、姓名(长度小于10的不包含空白字符的非空字符串)和3门课程的成绩([0,100]区间内的整数),要求输出总分最高学生的姓名、学号和总分。

输入格式:

输入在一行中给出正整数N(≤10)。随后N行,每行给出一位学生的信息,格式为“学号 姓名 成绩1 成绩2 成绩3”,中间以空格分隔。

输出格式:

在一行中输出总分最高学生的姓名、学号和总分,间隔一个空格。题目保证这样的学生是唯一的。

#include <stdio.h>
#include <string.h>

struct list
{
    char id[6];
    char name[100];
    int score1;
    int score2;
    int score3;
};

int main()
{
    int n, max, k;
    scanf("%d", &n);
    struct list s[n];
    for (int i = 0; i < n; i++)
    {
        scanf("%s %s %d %d %d", s[i].id, s[i].name, &s[i].score1, &s[i].score2, &s[i].score3);
        if (i == 0 || (s[i].score1 + s[i].score2 + s[i].score3) > max)
        {
            max = s[i].score1 + s[i].score2 + s[i].score3;
            k = i;
        }
    }
    printf("%s %s %d", s[k].name, s[k].id, max);
    return 0;
}

7-3 通讯录排序

输入n个朋友的信息,包括姓名、生日、电话号码,本题要求编写程序,按照年龄从大到小的顺序依次输出通讯录。题目保证所有人的生日均不相同。

输入格式:

输入第一行给出正整数n(<10)。随后n行,每行按照“姓名 生日 电话号码”的格式给出一位朋友的信息,其中“姓名”是长度不超过10的英文字母组成的字符串,“生日”是yyyymmdd格式的日期,“电话号码”是不超过17位的数字及+-组成的字符串。

输出格式:

按照年龄从大到小输出朋友的信息,格式同输出。

#include <stdio.h>
#include <string.h>

struct friend
{
    char name[100];
    int birth;
    char tel[18];
};

int n;
void BubbleSort(struct friend s[]);

int main()
{
    scanf("%d", &n);
    struct friend s[n];
    for (int i = 0; i < n; i++)
        scanf("%s %d %s", s[i].name, &s[i].birth, s[i].tel);
    BubbleSort(s);
    for (int i = 0; i < n; i++)
        printf("%s %d %s\n", s[i].name, s[i].birth, s[i].tel);
    return 0;
}
void BubbleSort(struct friend s[])
{
    for (int i = 0; i < n - 1; i++)
        for (int j = 0; j < n - i - 1; j++)
            if (s[j].birth > s[j + 1].birth)
            {
                struct friend temp = s[j + 1];
                s[j + 1] = s[j];
                s[j] = temp;
            }
}

7-4 一帮一

“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。

输入格式:

输入第一行给出正偶数N(≤50),即全班学生的人数。此后N行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。

输出格式:

每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。

#include <stdio.h>

struct Student
{
    char gender;
    char name[9];
    int flag;
};

int main()
{
    int n;
    char p;
    scanf("%d", &n);
    struct Student student[n];
    getchar();
    for (int i = 0; i < n; i++)
    {
        scanf("%c %s", &student[i].gender, student[i].name);
        getchar();
        student[i].flag = 0;
    }
    for (int i = 0; i < n; i++)
    {
        if (student[i].gender == '1')
            p = '0';
        else
            p = '1';
        for (int j = n - 1; j >= 0; j--)
        {
            if (student[j].gender == p && student[j].flag == 0)
            {
                printf("%s %s\n", student[i].name, student[j].name);
                student[j].flag = 1;
                student[i].flag = 1;
                break;
            }
        }
    }
    return 0;
}

先修课-2024-9

7-1 删除重复字符

本题要求编写程序,将给定字符串去掉重复的字符后,按照字符ASCII码顺序从小到大排序后输出。

输入格式:

输入是一个以回车结束的非空字符串(少于80个字符)。

输出格式:

输出去重排序后的结果字符串。

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main()
{
    char input[80];
    char output[80];
    bool flag[128] = {false};
    int index = 0;
    fgets(input, 80, stdin);
    input[strcspn(input, "\n")] = '\0';
    for (int i = 0; input[i] != '\0'; i++)
    {
        if (!flag[(int)input[i]])
        {
            flag[(int)input[i]] = true;
            output[index++] = input[i];
        }
    }
    output[index] = '\0';
    for (int i = 0; i < index - 1; i++)
    {
        for (int j = i + 1; j < index; j++)
        {
            if (output[i] > output[j])
            {
                char temp = output[i];
                output[i] = output[j];
                output[j] = temp;
            }
        }
    }
    printf("%s\n", output);
    return 0;
}

7-2 输出GPLT

给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。

输入格式:

输入在一行中给出一个长度不超过10000的、仅由英文字母构成的非空字符串。

输出格式:

在一行中按题目要求输出排序后的字符串。题目保证输出非空。

#include <stdio.h>
int main()
{
    char str[10001];
    int countG = 0, countP = 0, countL = 0, countT = 0;
    int i;
    scanf("%s", str);
    for (i = 0; str[i] != '\0'; i++)
    {
        char ch = str[i];
        if (ch >= 'a' && ch <= 'z')
            ch = ch - ('a' - 'A');
        if (ch == 'G')
            countG++;
        else if (ch == 'P')
            countP++;
        else if (ch == 'L')
            countL++;
        else if (ch == 'T')
            countT++;
    }
    while (countG > 0 || countP > 0 || countL > 0 || countT > 0)
    {
        if (countG > 0)
        {
            printf("G");
            countG--;
        }
        if (countP > 0)
        {
            printf("P");
            countP--;
        }
        if (countL > 0)
        {
            printf("L");
            countL--;
        }
        if (countT > 0)
        {
            printf("T");
            countT--;
        }
    }
    return 0;
}

7-3 A-B

本题要求你计算AB。不过麻烦的是,AB都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串AB

输入格式:

输入在2行中先后给出字符串AB。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

输出格式:

在一行中打印出AB的结果字符串。

#include <stdio.h>
int main()
{
    char A[100001], B[100001];
    int flag[128] = {0};
    fgets(A, 100001, stdin);
    fgets(B, 100001, stdin);
    for (int i = 0; B[i] != '\0'; i++)
    {
        flag[(int)B[i]] = 1;
    }
    for (int i = 0; A[i] != '\0'; i++)
    {
        if (flag[(int)A[i]] == 0)
        {
            printf("%c", A[i]);
        }
    }
    return 0;
}

7-4 检查密码

本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能。该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母、数字和小数点 .,还必须既有字母也有数字。

输入格式:

输入第一行给出一个正整数 N(≤ 100),随后 N 行,每行给出一个用户设置的密码,为不超过 80 个字符的非空字符串,以回车结束。

注意: 题目保证不存在只有小数点的输入。

输出格式:

对每个用户的密码,在一行中输出系统反馈信息,分以下5种:

  • 如果密码合法,输出Your password is wan mei.
  • 如果密码太短,不论合法与否,都输出Your password is tai duan le.
  • 如果密码长度合法,但存在不合法字符,则输出Your password is tai luan le.
  • 如果密码长度合法,但只有字母没有数字,则输出Your password needs shu zi.
  • 如果密码长度合法,但只有数字没有字母,则输出Your password needs zi mu.
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>
int main()
{
    int n;
    scanf("%d", &n);
    getchar();
    char password[82];
    for (int i = 0; i < n; i++)
    {
        fgets(password, 82, stdin);
        password[strcspn(password, "\n")] = '\0';
        int length = strlen(password);
        bool digit = false;
        bool alpha = false;
        bool invalid_char = false;
        if (length < 6)
            printf("Your password is tai duan le.\n");
        else
        {
            for (int j = 0; j < length; j++)
            {
                if (isdigit(password[j]))
                    digit = true;
                else if (isalpha(password[j]))
                    alpha = true;
                else if (password[j] != '.')
                    invalid_char = true;
            }
            if (invalid_char)
                printf("Your password is tai luan le.\n");
            else if (!digit)
                printf("Your password needs shu zi.\n");
            else if (!alpha)
                printf("Your password needs zi mu.\n");
            else
                printf("Your password is wan mei.\n");
        }
    }
    return 0;
}