成绩单
题目
成绩单和薛定谔的猫一样,打开他之前你都不知道你会不会完蛋。
小J和小R刚刚经历了半期考试,刚刚拿到了成绩单。
小R:"这么多成绩,感觉都不好对比,我想看看更加格式化一点的成绩单"
小J:"这还不简单,看我的。"
起初,小J以为只有几个人的成绩以为很快就可以手动排好,当他看到小R拿出的整个年级的成绩时陷入了深深的绝望,而现在只能请你来帮帮他了!
现在小J拿到了每个人对应的姓名和三个科目的成绩,现在需要你帮助他按照样例的格式完成排版,按照成绩总分从高到低排序,如果一样则依次考虑计算机网络、程序设计、数据结构和姓名字典序高到低排序。
输入:第一行一个整数 N,学生人数。接下来 N 行,对于每行:一个字符串,表示学生姓名,不超过10个字符;三个数字,表示计算机网络、程序设计、数据结构的成绩。
输出:按照格式输出成绩单,姓名栏占位10字符,其余栏目占位8字符,均使用右对齐。
样例1:
输入
2 wangwang 90 100 90 anan 99 99 99
输出
------------------------------------------------ | name| Network| Program| Date| Sum| ------------------------------------------------ | anan| 99| 99| 99| 297| | wangwang| 90| 100| 90| 280| ------------------------------------------------
样例2:
输入
3 wangwang 99 100 60 anan 100 100 100 zhangSan 60 60 70
输出
------------------------------------------------ | name| Network| Program| Date| Sum| ------------------------------------------------ | anan| 100| 100| 100| 300| | wangwang| 99| 100| 60| 259| | zhangsan| 60| 60| 70| 190| ------------------------------------------------
提示:对于 30% 的数据,保证 n≤100。对于 70% 的数据,保证 n≤1000。对于 100% 的数据,保证 n≤20000。
思路
用一个结构体存储每位学生的姓名和三门成绩(以及预先算好的总分)。自定义 cmp 函数,依次按总分、计算机网络、程序设计、数据结构、姓名字典序降序排列——每一级只要不相等就直接返回,不用写嵌套 if-else。输出时用 setw 控制列宽(姓名 10、其余各 8),分隔线恰好 48 个 -。
#include<bits/stdc++.h>
using namespace std;
struct Student {
string name;
int net, prog, data, sum;
};
// 排序规则
bool cmp(const Student &a, const Student &b) {
if (a.sum != b.sum) return a.sum > b.sum;
if (a.net != b.net) return a.net > b.net;
if (a.prog != b.prog) return a.prog > b.prog;
if (a.data != b.data) return a.data > b.data;
return a.name > b.name; // 字典序降序
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<Student> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i].name >> v[i].net >> v[i].prog >> v[i].data;
v[i].sum = v[i].net + v[i].prog + v[i].data;
}
sort(v.begin(), v.end(), cmp);
// 表头
cout << "------------------------------------------------\n";
cout << "|" << setw(10) << "name"
<< "|" << setw(8) << "Network"
<< "|" << setw(8) << "Program"
<< "|" << setw(8) << "Date"
<< "|" << setw(8) << "Sum"
<< "|\n";
cout << "------------------------------------------------\n";
// 数据
for (auto &s : v) {
cout << "|" << setw(10) << s.name
<< "|" << setw(8) << s.net
<< "|" << setw(8) << s.prog
<< "|" << setw(8) << s.data
<< "|" << setw(8) << s.sum
<< "|\n";
}
cout << "------------------------------------------------\n";
return 0;
}
复杂度分析
- 时间复杂度:O(n log n),排序主导
- 空间复杂度:O(n),存储 n 个学生
cmp 函数里的简洁判断很好用——每一级直接 return,不用一堆嵌套的 if-else,清晰很多。另外这道题温习了结构体的使用,把相关数据打包在一起确实比散装变量好管理。