题目

成绩单和薛定谔的猫一样,打开他之前你都不知道你会不会完蛋。

小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 个 -

C++ · p51.cpp
#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,清晰很多。另外这道题温习了结构体的使用,把相关数据打包在一起确实比散装变量好管理。

← 返回菜鸟的coding