首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >杨校老师课堂之信息学奥赛结构体知识训练

杨校老师课堂之信息学奥赛结构体知识训练

原创
作者头像
杨校
修改2025-02-21 23:00:16
修改2025-02-21 23:00:16
18100
代码可运行
举报
文章被收录于专栏:C++信息学奥赛C++信息学奥赛
运行总次数:0
代码可运行

1. 旗鼓相当的对手

题目描述

现有N(N≤1000) 名同学参加了期末考试,并且获得了每名同学的信息:语文、数学、英语成绩(均为不超过 150 的自然数)。如果某对学生 <i,j> 的每一科成绩的分差都不大于 5,且总分分差不大于 10,那么这对学生就是“旗鼓相当的对手”。现在想知道这些同学中,有几对“旗鼓相当的对手”?同样一个人可能会和其他好几名同学结对。

输入描述

第一行一个正整数 N。

接下来 N 行,每行三个整数,其中第 i 行表示第 i名同学的语文、数学、英语成绩。最先读入的同学编号为 1。

输出描述

输出一个整数,表示“旗鼓相当的对手”的对数。

样例

输入

3

90 90 90

85 95 90

80 100 91

输出

2

解题思路:

  1. 数据结构定义:定义名为node的结构体,包含语文、数学、英语成绩及总成绩四个成员变量,用于存储学生成绩信息。同时定义结构体数组stu,用于存储最多 1005 个学生的成绩数据。
  2. 输入学生数量及成绩:通过cin从标准输入读取学生数量n,然后使用循环遍历每个学生,依次读取其语文、数学、英语成绩,并计算出总成绩存储在结构体数组相应元素中。
  3. 比较成绩并统计:使用两层嵌套循环遍历学生数组,外层循环变量为i,内层循环变量为jj > i)。对于每对学生ij,通过abs函数分别判断他们语文、数学、英语成绩差值是否均不超过 5,以及总成绩差值是否不超过 10。若满足这些条件,则将计数器cnt加 1。
  4. 输出结果:循环结束后,通过cout输出计数器cnt的值,即符合条件的学生对数。
代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
using namespace std;

// 定义结构体node,用于存储学生的各科成绩和总成绩
struct node {
    int Chinese;  // 语文成绩
    int math;     // 数学成绩
    int English;  // 英语成绩
    int sum;      // 总成绩
} stu[1005];    // 定义结构体数组stu,最多存储1005个学生的信息

int main() {
    int n, cnt = 0;  // 定义整数n用于存储学生数量,cnt用于统计符合条件的学生对数,初始化为0
    cin >> n;  // 从标准输入读取学生数量n
    for (int i = 1; i <= n; ++i) {
        // 依次读取每个学生的语文、数学、英语成绩
        cin >> stu[i].Chinese >> stu[i].math >> stu[i].English;
        // 计算每个学生的总成绩
        stu[i].sum = stu[i].Chinese + stu[i].math + stu[i].English;
    }
    for (int i = 1; i < n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
            // 判断学生i和学生j的语文、数学、英语成绩差值是否都不超过5,总成绩差值是否不超过10
            if (abs(stu[i].Chinese - stu[j].Chinese) <= 5 &&
                abs(stu[i].math - stu[j].math) <= 5 &&
                abs(stu[i].English - stu[j].English) <= 5 &&
                abs(stu[i].sum - stu[j].sum) <= 10) {
                ++cnt;  // 如果符合条件,cnt加1
            }
        }
    }
    cout << cnt << endl;  // 输出符合条件的学生对数
    return 0;
}

2. 学生管理系统

题目描述

学生信息的准确性和时效性成为了她日常工作中的关键一环。鉴于信息班中学生人数众多,手动统计与更新学生信息不仅耗时费力,还容易出错,因此,你作为信息班的一员,准备开发一个专门的信息管理系统来协助小可老师高效地完成这项任务。

该系统设计旨在实现以下核心功能,以全面覆盖学生信息管理的各个方面:

1、添加学生功能:每当班级迎来新成员时,小可老师可以输入学员数量 n,然后快速输入 n 位新生的学号 ID 、姓名 name、年龄 age、性别 gender 以及信息学成绩 score等关键信息。(注:学生信息具体数据类型可以参考样例和数据范围说明)

2、删除学生功能:面对学生转班或离校的情况,系统可以通过学号快速定位并删除学生信息的功能。

3、修改学生信息功能:考虑到学生信息可能因各种原因需要更正(如年龄增长、成绩更新等),系统可以通过学号检索到具体学生后,对其信息进行修改。

4、查询学生信息功能:为了快速获取某位学生的详细信息,系统提供了按学号查询的功能。

5、统计学生数据功能:系统能够自动计算并展示全班学生的信息学成绩平均值。

6、清空数据功能:随着学年的结束和班级学生的毕业,系统提供了清空当前班级所有信息的选项。

输入描述

每次操作,只能是下列七个操作中一个,每次操作将按照操作提示进行输入,数据保证合法。

1、添加学生功能:输入一行 insert n,表示进行添加学生功能, n表示新加学生的数量,然后输入 nn 行信息,依次为 ID、name、age、gender、score

2、删除学生功能:输入一行 del ID,表示进行删除学号为 ID的学生信息。

3、修改学生信息功能:输入一行 update ID,表示进行更新学号为 ID 的学生信息,然后第二行输入学生信息,依次为 ID、name、age、gender、score

4、查询学生信息功能:输入一行 Find ID,表示查询学号为 ID的学生信息,然后输出一行,依次为学生的 ID、name、age、gender、score

5、统计学生数据功能:输入一行 calc,表示统计学生数据,然后输出一行,为当前班级成绩的平均值。

6、清空数据功能:输入一行 clear,表示清空,清空表示所有学生信息都被删除。

7、退出系统,输入一行 exit,表示退出系统,此时程序停止执行。

输出描述

每次执行功能 4,输出一行,信息以一个空格分隔,依次为学生的 ID、name、age、gender、score

每次执行功能 5,输出一行,包含一个数字,保留两位小数,表示平均分。

当执行功能 7,按存储顺序输出所有学生信息,每个学生信息占一行,信息以一个空格分隔,依次为学生的 ID、name、age、gender、score,然后结束程序。

输入样例

insert 5 20000101011 xiaoke 15 f 100 20000101012 xiaoda 25 m 70 20000101013 xiaoya 35 f 67 20000101014 keke 11 f 78 20000101015 dada 19 m 26 del 20000101013 calc update 20000101014 20000101014 kaka 12 m 90 Find 20000101015 clear insert 2 20000101011 xiaoke 15 f 100 20000101012 xiaoda 25 m 70 exit

输出样例

68.50 20000101015 dada 19 m 26 20000101011 xiaoke 15 f 100 20000101012 xiaoda 25 m 70

注意

本题目输入输出量较大,推荐使用更快的输入输出方式,例如:scanf、printf

数据范围

每组操作数量最多不超过 10001000 次。

添加学生功能中,每次 nn 不超过 2020。

学号 ID 为11位数,姓名 name 长度不超过 1010 且都为小写字母,年龄 age 在 00 到 100100 之间,性别 genderm 或者 f ,信息学成绩 score 为整数,在 00 到 100100 之间。

数据保证学号ID不重复。

  1. 数据结构设计
  • 结构体定义:定义 Student 结构体来存储单个学生的信息,包含学号 id、姓名 name、年龄 age、性别 gender 和成绩 score
  • 静态数组存储:使用静态数组 students[20005] 存储所有学生的信息,同时定义全局变量 studentCount 记录当前学生数量,totalScore 记录所有学生的总成绩。
  1. 功能函数实现
  • 添加学生(insertStudents):
    • 接收要添加的学生数量 n 作为参数。
    • 循环 n 次,每次读取一个学生的学号、姓名、年龄、性别和成绩,并将其存储到数组中。
    • 每添加一个学生,更新 studentCounttotalScore
  • 删除学生(deleteStudent):
    • 接收要删除的学生的学号 id 作为参数。
    • 遍历数组,找到学号匹配的学生。
    • totalScore 中减去该学生的成绩,将其后的学生信息依次前移覆盖该学生,同时 studentCount 减 1。
  • 修改学生信息(updateStudent):
    • 接收要修改信息的学生的学号 id 作为参数。
    • 遍历数组,找到学号匹配的学生。
    • 先从 totalScore 中减去该学生原来的成绩,再读取新的信息并更新到数组中,最后将新成绩累加到 totalScore 中。
  • 查找学生信息(findStudent):
    • 接收要查找的学生的学号 id 作为参数。
    • 遍历数组,找到学号匹配的学生并输出其信息。
  • 统计学生数据(calculateAverage):
    • studentCount 为 0,输出 0.00
    • 否则,计算并输出 totalScore 除以 studentCount 的结果,保留两位小数。
  • 清空数据(clearData):将 studentCounttotalScore 重置为 0,相当于清空所有学生信息。
  • 输出所有学生信息(printAllStudents):遍历数组,依次输出每个学生的信息。
  1. 主函数逻辑
  • 使用 while (true) 循环不断读取用户输入的操作指令。
  • 根据不同的操作指令,执行相应的功能函数:
    • 若指令为 insert,读取要添加的学生数量 n,调用 insertStudents 函数。
    • 若指令为 del,读取要删除的学生的学号 id,调用 deleteStudent 函数。
    • 若指令为 update,读取要修改信息的学生的学号 id,调用 updateStudent 函数。
    • 若指令为 Find,读取要查找的学生的学号 id,调用 findStudent 函数。
    • 若指令为 calc,调用 calculateAverage 函数。
    • 若指令为 clear,调用 clearData 函数。
    • 若指令为 exit,调用 printAllStudents 函数输出所有学生信息,然后退出循环,结束程序。
  1. 输入输出优化

考虑到输入输出量较大,部分输入使用 scanf,部分输出使用 printf 以提高效率。对于字符串输入,使用 cin 处理姓名和性别等信息。同时,使用 std::string 类型存储操作指令,方便进行字符串比较。

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;

// 定义学生结构体,用于存储学生的各项信息
struct Student {
    long long id;  // 学生的学号,使用 long long 类型以适应可能较长的学号
    string name;   // 学生的姓名,使用 string 类型方便处理字符串
    int age;       // 学生的年龄,使用 int 类型存储整数
    string gender; // 学生的性别,使用 string 类型存储 "m" 或 "f" 等字符串
    int score;     // 学生的信息学成绩,使用 int 类型存储整数
};

// 定义一个静态数组,用于存储学生信息,最多可存储 20005 个学生
Student students[20005];
// 记录当前学生的数量,初始化为 0
int studentCount = 0;
// 记录所有学生的总成绩,初始化为 0
int totalScore = 0;

// 添加学生的函数,参数 n 表示要添加的学生数量
void insertStudents(int n) {
    // 循环 n 次,依次输入每个学生的信息
    for (int i = 0; i < n; ++i) {
        // 学生数量加 1
        studentCount++;
        // 读取学生的学号
        scanf("%lld", &students[studentCount].id);
        // 读取学生的姓名
        cin >> students[studentCount].name;
        // 读取学生的年龄
        scanf("%d", &students[studentCount].age);
        // 读取学生的性别
        cin >> students[studentCount].gender;
        // 读取学生的成绩
        scanf("%d", &students[studentCount].score);
        // 将该学生的成绩累加到总成绩中
        totalScore += students[studentCount].score;
    }
}

// 删除学生的函数,参数 id 表示要删除的学生的学号
void deleteStudent(long long id) {
    // 遍历所有学生,查找要删除的学生
    for (int i = 1; i <= studentCount; ++i) {
        if (students[i].id == id) {
            // 从总成绩中减去要删除学生的成绩
            totalScore -= students[i].score;
            // 将后面的学生信息依次向前移动,覆盖要删除的学生信息
            for (int j = i; j < studentCount; ++j) {
                students[j] = students[j + 1];
            }
            // 学生数量减 1
            studentCount--;
            // 找到并删除学生后,提前返回
            return;
        }
    }
}

// 修改学生信息的函数,参数 id 表示要修改信息的学生的学号
void updateStudent(long long id) {
    // 遍历所有学生,查找要修改信息的学生
    for (int i = 1; i <= studentCount; ++i) {
        if (students[i].id == id) {
            // 从总成绩中减去该学生原来的成绩
            totalScore -= students[i].score;
            // 读取新的学号
            scanf("%lld", &students[i].id);
            // 读取新的姓名
            cin >> students[i].name;
            // 读取新的年龄
            scanf("%d", &students[i].age);
            // 读取新的性别
            cin >> students[i].gender;
            // 读取新的成绩
            scanf("%d", &students[i].score);
            // 将新的成绩累加到总成绩中
            totalScore += students[i].score;
            // 找到并修改学生信息后,提前返回
            return;
        }
    }
}

// 查找学生信息的函数,参数 id 表示要查找的学生的学号
void findStudent(long long id) {
    // 遍历所有学生,查找指定学号的学生
    for (int i = 1; i <= studentCount; ++i) {
        if (students[i].id == id) {
            // 找到学生后,输出该学生的信息
            printf("%lld %s %d %s %d\n", students[i].id, students[i].name.c_str(), students[i].age, students[i].gender.c_str(), students[i].score);
            // 找到学生后,提前返回
            return;
        }
    }
}

// 统计学生数据的函数,用于计算并输出学生的平均成绩
void calculateAverage() {
    // 如果学生数量为 0,输出 0.00
    if (studentCount == 0) {
        printf("0.00\n");
    } else {
        // 计算平均成绩并输出,保留两位小数
        printf("%.2f\n", (double)totalScore / studentCount);
    }
}

// 清空数据的函数,将学生数量和总成绩重置为 0
void clearData() {
    studentCount = 0;
    totalScore = 0;
}

// 输出所有学生信息的函数,遍历所有学生并输出其信息
void printAllStudents() {
    for (int i = 1; i <= studentCount; ++i) {
        printf("%lld %s %d %s %d\n", students[i].id, students[i].name.c_str(), students[i].age, students[i].gender.c_str(), students[i].score);
    }
}

int main() {
    string op;  // 用于存储用户输入的操作指令
    while (true) {
        // 读取用户输入的操作指令
        cin >> op;
        if (op == "insert") {
            int n;
            // 读取要添加的学生数量
            scanf("%d", &n);
            // 调用添加学生的函数
            insertStudents(n);
        } else if (op == "del") {
            long long id;
            // 读取要删除的学生的学号
            scanf("%lld", &id);
            // 调用删除学生的函数
            deleteStudent(id);
        } else if (op == "update") {
            long long id;
            // 读取要修改信息的学生的学号
            scanf("%lld", &id);
            // 调用修改学生信息的函数
            updateStudent(id);
        } else if (op == "Find") {
            long long id;
            // 读取要查找的学生的学号
            scanf("%lld", &id);
            // 调用查找学生信息的函数
            findStudent(id);
        } else if (op == "calc") {
            // 调用统计学生数据的函数
            calculateAverage();
        } else if (op == "clear") {
            // 调用清空数据的函数
            clearData();
        } else if (op == "exit") {
            // 调用输出所有学生信息的函数
            printAllStudents();
            // 退出循环,结束程序
            break;
        }
    }
    return 0;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 旗鼓相当的对手
    • 题目描述
    • 输入描述
    • 输出描述
    • 样例
    • 输入
    • 输出
  • 2. 学生管理系统
    • 题目描述
    • 输入描述
    • 输出描述
    • 输入样例
    • 输出样例
    • 注意
    • 数据范围
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档