Files
project1/第01课-C++自带函数/编程题-教师版.md
2026-07-02 16:54:05 +08:00

14 KiB
Raw Blame History

第1课编程题教师版

本课知识点覆盖表

核心知识点 GESP等级 对应课堂题
sqrtpowabs<cmath> 一级巩固/二级拓展 课堂1
maxminswap<algorithm> 二级 课堂2
maxmin 综合应用 二级 课堂3
isalphaisdigitislowerisuppertolowertoupper 一级/二级 课堂4

难度均为本课内部的相对难度。参考程序采用 C++17。

一、课堂练习4题

课堂1三点中最近的一对【适中】

题目描述: 输入平面上三个点的坐标,求三对点之间的最短距离,结果保留两位小数。要求使用 sqrtpowmin

输入格式: 输入六个实数,依次表示三个点的横坐标和纵坐标。

输出格式: 输出最短距离,保留两位小数。

数据范围: 每个坐标的绝对值不超过 1000。

输入样例:

0 0 3 4 0 2

输出样例:

2.00

解题思路: 用勾股定理分别求出三段距离,再用 min 取最小值。

参考代码:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <iomanip>
using namespace std;

double distance(double x1, double y1, double x2, double y2) {
    return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
}

int main() {
    double x1, y1, x2, y2, x3, y3;
    cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
    double d1 = distance(x1, y1, x2, y2);
    double d2 = distance(x1, y1, x3, y3);
    double d3 = distance(x2, y2, x3, y3);
    cout << fixed << setprecision(2) << min(d1, min(d2, d3));
    return 0;
}

易错提醒: sqrt 返回浮点数;格式化输出需要包含 <iomanip>

课堂2整理三个数【适中】

题目描述: 输入三个整数,第一行输出最大值和最小值;再使用 swap 将三个变量调整为升序,第二行输出调整结果。

输入格式: 输入三个整数。

输出格式: 第一行输出最大值和最小值;第二行输出升序结果。

数据范围: -10^9≤a,b,c≤10^9

输入样例:

8 2 5

输出样例:

8 2
2 5 8

解题思路: 用嵌套的 maxmin 求最值;再进行三次相邻比较,需要时调用 swap

参考代码:

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    cout << max(a, max(b, c)) << " " << min(a, min(b, c)) << "\n";
    if (a > b) swap(a, b);
    if (b > c) swap(b, c);
    if (a > b) swap(a, b);
    cout << a << " " << b << " " << c;
    return 0;
}

易错提醒: swap 的参数必须是两个变量,不能传入 a+b 这样的表达式。

课堂3去掉最高分和最低分【适中】

题目描述: 输入若干个评委分数,去掉一个最高分和一个最低分,输出剩余分数之和。不得使用排序。

输入格式: 第一行输入评委人数;第二行输入所有评委给出的分数。

输出格式: 输出剩余分数之和。

数据范围: 3≤n≤100,分数为 0100

输入样例:

5
9 7 10 8 6

输出样例:

24

解题思路: 遍历时同时计算总分、最高分和最低分,最后用总分减去两个极值。

参考代码:

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int n, score, sum = 0, biggest, smallest;
    cin >> n;
    cin >> score;
    sum = biggest = smallest = score;
    for (int i = 1; i < n; i++) {
        cin >> score;
        sum += score;
        biggest = max(biggest, score);
        smallest = min(smallest, score);
    }
    cout << sum - biggest - smallest;
    return 0;
}

易错提醒: 最高分和最低分要用第一个合法分数初始化;即使最高分重复,也只去掉一个。

课堂4字符身份证【适中】

题目描述: 输入一个可见字符。若为字母,输出 LETTER 和相反大小写的字符;若为数字,输出 DIGIT;否则输出 OTHER

输入格式: 一个可见字符。

输出格式: 按题目要求输出。

数据范围: 标准 ASCII 可见字符。

输入样例:

G

输出样例:

LETTER g

解题思路:isalphaisdigit 分类,用 islowerisupper 判断大小写,再调用 touppertolower 转换。

参考代码:

#include <iostream>
#include <cctype>
using namespace std;

int main() {
    char c;
    cin >> c;
    if (isalpha(c)) {
        cout << "LETTER ";
        if (islower(c)) cout << (char)toupper(c);
        else if (isupper(c)) cout << (char)tolower(c);
    } else if (isdigit(c)) {
        cout << "DIGIT";
    } else {
        cout << "OTHER";
    }
    return 0;
}

易错提醒: tolowertoupper 返回的是字符编码,输出字符时应转换为 char

二、课后作业3题

课后1离原点的距离【简单】

题目描述: 输入点 (x,y),输出它到原点的距离,保留两位小数。

输入格式: 输入两个实数,依次表示横坐标和纵坐标。

输出格式: 距离,保留两位小数。

数据范围: 坐标绝对值不超过 1000。

输入样例:

3 4

输出样例:

5.00

解题思路: 根据勾股定理计算 sqrt(pow(x,2)+pow(y,2))

参考代码:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    double x, y;
    cin >> x >> y;
    cout << fixed << setprecision(2)
         << sqrt(pow(x, 2) + pow(y, 2));
    return 0;
}

易错提醒: 不要忘记 <cmath><iomanip>

课后2两数差的绝对值【简单】

题目描述: 输入两个整数,输出它们差的绝对值。

输入格式: 输入两个整数。

输出格式: 输出 |a-b|

数据范围: 两数绝对值不超过 10000。

输入样例:

3 9

输出样例:

6

解题思路: 直接调用 abs(a-b)

参考代码:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int a, b;
    cin >> a >> b;
    cout << abs(a - b);
    return 0;
}

易错提醒: 先求差再取绝对值,不要误写成 abs(a)-abs(b)

课后3数字还是字母【简单】

题目描述: 输入一个字符。是数字输出 1,是字母输出 2,其他字符输出 0

输入格式: 一个字符。

输出格式: 一个整数。

数据范围: 标准 ASCII 可见字符。

输入样例:

8

输出样例:

1

解题思路: 依次调用 isdigitisalpha

参考代码:

#include <iostream>
#include <cctype>
using namespace std;

int main() {
    char c;
    cin >> c;
    if (isdigit(c)) cout << 1;
    else if (isalpha(c)) cout << 2;
    else cout << 0;
    return 0;
}

易错提醒: 字符数字 '8' 与整数 8 不同。

三、扩展练习7题

扩展1正方形对角线【基础综合】

题目描述: 输入正方形边长,输出对角线长度,保留三位小数。

输入格式: 输入一个正实数,表示正方形的边长。

输出格式: 对角线长度。

数据范围: 0<a≤10000

输入样例:

2

输出样例:

2.828

解题思路: 对角线为 sqrt(2)*a

参考代码:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    double a;
    cin >> a;
    cout << fixed << setprecision(3) << sqrt(2.0) * a;
    return 0;
}

易错提醒: 使用 2.0 可以明确进行浮点运算。

扩展2三个数的中间数【基础综合】

题目描述: 输入三个互不相同的整数,使用 maxmin 输出大小居中的数。

输入格式: 三个整数。

输出格式: 中间数。

数据范围: 每个数的绝对值不超过 10^9

输入样例:

9 2 6

输出样例:

6

解题思路: 三数之和减去最大值和最小值。

参考代码:

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    long long a, b, c;
    cin >> a >> b >> c;
    long long biggest = max(a, max(b, c));
    long long smallest = min(a, min(b, c));
    cout << a + b + c - biggest - smallest;
    return 0;
}

易错提醒: 三数之和可能超过 int,这里使用 long long

扩展3成绩极差【中等】

题目描述: 输入若干个成绩,输出最低分、最高分以及两者之差。

输入格式: 第一行输入成绩数量;第二行输入所有成绩。

输出格式: 依次输出最低分、最高分和极差。

数据范围: 1≤n≤100,成绩为 0100

输入样例:

4
80 60 90 70

输出样例:

60 90 30

解题思路: 用第一个成绩初始化最值,随后逐一调用 maxmin 更新。

参考代码:

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int n, score, biggest, smallest;
    cin >> n;
    cin >> score;
    biggest = smallest = score;
    for (int i = 1; i < n; i++) {
        cin >> score;
        biggest = max(biggest, score);
        smallest = min(smallest, score);
    }
    cout << smallest << " " << biggest << " " << biggest - smallest;
    return 0;
}

易错提醒: 当只有一个成绩时,最低分和最高分相同,极差为 0。

扩展4口令规范化【中等】

题目描述: 输入一个不含空格的口令,把其中所有字母转成大写,数字和符号保持不变。

输入格式: 一个不含空格的字符串。

输出格式: 转换后的字符串。

数据范围: 字符串长度不超过 100。

输入样例:

GesP2026!

输出样例:

GESP2026!

解题思路: 逐个检查字符;是字母就调用 toupper

参考代码:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main() {
    string s;
    cin >> s;
    for (int i = 0; i < (int)s.size(); i++) {
        if (isalpha(s[i])) s[i] = (char)toupper(s[i]);
    }
    cout << s;
    return 0;
}

易错提醒: 不要改动数字和符号。

扩展5离目标最近的数【中等】

题目描述: 输入 n 个整数和目标值 t,输出与 t 的差的绝对值最小的数;若并列,输出较小者。

输入格式: 第一行输入整数数量和目标值;第二行输入所有整数。

输出格式: 满足条件的整数。

数据范围: 1≤n≤100,输入整数绝对值不超过 10000。

输入样例:

4 10
8 12 15 3

输出样例:

8

解题思路: 用第一个数初始化答案;比较 abs(x-t),相等时比较数值大小。

参考代码:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int n, t, x, answer;
    cin >> n >> t >> answer;
    for (int i = 1; i < n; i++) {
        cin >> x;
        if (abs(x - t) < abs(answer - t) ||
            (abs(x - t) == abs(answer - t) && x < answer)) {
            answer = x;
        }
    }
    cout << answer;
    return 0;
}

易错提醒: 不能把答案初始化为 0因为 0 不一定在输入中。

扩展6最接近平均值的成绩【略难】

题目描述: 输入 n 个整数成绩,求平均值,并输出最接近平均值的成绩;若并列,输出较小者。

输入格式: 第一行输入成绩数量;第二行输入所有成绩。

输出格式: 一个成绩。

数据范围: 1≤n≤100,成绩为 0100

输入样例:

4
60 70 80 100

输出样例:

80

解题思路: 先求浮点平均值,再使用 abs 进行二次打擂台。

参考代码:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    int n, a[105], sum = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum += a[i];
    }
    double average = 1.0 * sum / n;
    int answer = a[0];
    for (int i = 1; i < n; i++) {
        double now = abs(a[i] - average);
        double best = abs(answer - average);
        if (now < best || (now == best && a[i] < answer)) {
            answer = a[i];
        }
    }
    cout << answer;
    return 0;
}

易错提醒: 平均值必须使用浮点除法;并列规则不能遗漏。

扩展7统一大小写并分类统计【略难】

题目描述: 输入一个不含空格的字符串,把所有字母转成小写,并统计原字符串中大写字母、小写字母和数字的数量。

输入格式: 输入一个不含空格的字符串。

输出格式: 第一行输出转换后的字符串;第二行依次输出三类字符数量。

数据范围: 字符串长度为 1100。

输入样例:

AbC2026xY

输出样例:

abc2026xy
3 3 4

解题思路: 遍历原字符串,先分类计数,再对字母调用 tolower

参考代码:

#include <iostream>
#include <cctype>
#include <string>
using namespace std;

int main() {
    string s;
    int upper = 0, lower = 0, digit = 0;
    cin >> s;
    for (char &c : s) {
        if (isupper(c)) upper++;
        else if (islower(c)) lower++;
        else if (isdigit(c)) digit++;
        if (isalpha(c)) c = (char)tolower(c);
    }
    cout << s << "\n";
    cout << upper << " " << lower << " " << digit;
    return 0;
}

易错提醒: 分类统计必须依据转换前的字符;数字不参与大小写转换。