题解:洛谷 P5740 最厉害的学生
【题目来源】
洛谷:P5740 【深基7.例9】最厉害的学生 - 洛谷(luogu.com.cn)
【题目描述】
现有 \(N\) 名同学参加了期末考试,并且获得了每名同学的信息:姓名(不超过 \(8\) 个字符的仅有英文小写字母的字符串)、语文、数学、英语成绩(均为不超过 \(150\) 的自然数)。总分最高的学生就是最厉害的,请输出最厉害的学生各项信息(姓名、各科成绩)。如果有多个总分相同的学生,输出靠前的那位。
【输入】
第一行输入一个正整数 \(N\),表示学生个数。
第二行开始,往下 \(N\) 行,对于每一行首先先输入一个字符串表示学生姓名,再输入三个自然数表示语文、数学、英语的成绩。均用空格相隔。
【输出】
输出最厉害的学生。
【输入样例】
3
senpai 114 51 4
lxl 114 10 23
fafa 51 42 60
【输出样例】
senpai 114 51 4
【核心思想】
-
问题分析:有 \(N\) 名学生,每名学生有姓名、语文、数学、英语成绩。需要找出总分最高的学生,并输出其所有信息。若总分相同,输出输入顺序靠前的那位。本质是一个结构体数组 + 遍历比较的问题,通过维护当前最高分及其索引,一次遍历即可得到答案。
-
算法选择:
- 结构体存储:使用结构体
Student封装姓名和三科成绩,便于管理。 - 线性扫描:遍历所有学生,计算总分并与当前最高分比较,若更高则更新记录。由于需要输出靠前的,仅在
tmp > max时更新,不更新等于的情况,自然保留了先出现的。 - 复杂度:时间复杂度 \(O(N)\),空间复杂度 \(O(N)\)。
- 结构体存储:使用结构体
-
关键步骤:
- 读入:读取 \(N\),然后循环读取每名学生的信息,存入结构体数组。
- 查找最高分:初始化
max = -1,mark = 0。对每个学生 \(i\):- 计算总分
sum = yu + shu + ying。 - 若
sum > max,则更新max = sum,mark = i。
- 计算总分
- 输出:输出
s[mark]的姓名和三科成绩。
-
时间/空间复杂度:
- 时间复杂度:\(O(N)\)。
- 空间复杂度:\(O(N)\)。
-
结构体与线性查找:
- 结构体优势:将相关数据(姓名、各科成绩)组织在一起,代码更清晰。
- 并列处理:使用
>而非>=来更新,保证了并列时保留更早出现的同学。 - 初始化:
max = -1或0均可,因为成绩非负。 - 适用场景:这类“查找最大值及对应信息”的问题,是结构体使用的经典入门题。
【算法标签】
普及- #模拟
【代码详解】
#include <bits/stdc++.h> // 包含标准库头文件(万能头文件)
using namespace std; // 使用标准命名空间
// 定义学生结构体
struct student
{
string name; // 学生姓名
int yu; // 语文成绩
int shu; // 数学成绩
int ying; // 英语成绩
int zong; // 总成绩(代码中未使用)
};
int main()
{
student s[1005]; // 定义学生数组,最多存储1005个学生
int n, mark, max = -1, tmp; // 定义变量:学生数n,最高分学生索引mark,最高分max,临时变量tmp
cin >> n; // 输入学生数量
// 输入每个学生的信息并计算最高分
for (int i = 1; i <= n; i++)
{
cin >> s[i].name >> s[i].yu >> s[i].shu >> s[i].ying; // 输入学生信息
tmp = s[i].yu + s[i].shu + s[i].ying; // 计算总分
// 更新最高分信息
if (tmp > max)
{
max = tmp; // 更新最高分
mark = i; // 记录最高分学生索引
}
}
// 输出最高分学生的信息
cout << s[mark].name << " " << s[mark].yu << " " << s[mark].shu << " " << s[mark].ying;
return 0; // 程序正常结束
}
【运行结果】
3
senpai 114 51 4
lxl 114 10 23
fafa 51 42 60
senpai 114 51 4
浙公网安备 33010602011771号