题解:P1093 [NOIP2007 普及组] 奖学金

· · 题解

题解:P1093 [NOIP2007 普及组] 奖学金

思路

这道题可以用结构体排序的方法做。

什么是结构体?

结构体(struct),可以看做是一系列称为成员元素的组合体。

可以看做是自定义的数据类型。

(以上摘自 OI-Wiki)

如果有些数据可以放在一起使用(如本题中一个学生的语数英三科放在一起排序),此时可以用结构体。

怎么定义结构体?

struct abc
{
    int a, b, c;
};

定义了一个结构体 abc,它的每个变量都拥有 abc 三个成员。

怎么定义一个结构体类型的变量?

和普通变量一样。

abc x, y = {3, 4}, *p, *q = &x, a[100] = {{0}};

这段代码定义了 abc 类型的两个变量(xy)、两个指向 abc 类型变量的指针(pq)、一个 abc 类型的数组。

abc y = {3, 4} 表明初始化 ya 成员为 3b 成员为 4

怎么使用这个结构体变量?

可以用 y.c 来表示 yc 成员。下面是一些例子:

y.c = 10; // 将 y 的 c 成员赋值为 10
cout << y.c; // 输出 y 的 c 成员
cin >> y.c; // 输入 y 的 c 成员

可以用 q->a(*q).a 表示 *q(即 q 指向的那个变量)的 a 成员。

可以用 a[i].b 表示 a 数组的第 i 个元素的 b 成员。

如何排序?

int b[100];
sort(b + l, b + r); // 将 b 数组的 l 到 r 从小到大排序。
sort(b + l, b + r, greater<int>()); // 将 b 数组的 l 到 r 从大到小排序。
bool cmp(abc/*类型*/ x, abc y)
{
    // return x.a < y.a; // 按照 a 成员排序。(注意 sort 是不稳定排序,所以 a 成员相等时顺序可能会换)
    return x.a < y.a || x.a == y.a && x.b < y.b || x.a == y.a && x.b == y.b && x.c < y.c;
    // a 成员为第一关键字、b 成员为第二关键字、c 成员为第三关键字排序。
}
sort(a + l, a + r, cmp); // 将 a 数组“按照 cmp 排序”

AC 代码

#include <bits/stdc++.h>
using namespace std;
struct st // 定义 st 结构体表示一个学生
{
    int id, ch, sum; // id 表示学号,ch 表示语文成绩,sum 表示成绩总和。
} s[310];
// struct st {...} s[310];
// 相当于
// struct st {...}; st s[310];
int n;
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int ma, en;
        cin >> s[i].ch >> ma >> en;
        s[i].id = i;
        s[i].sum = s[i].ch + ma + en;
    }
    sort(s + 1, s + 1 + n, [](st l, st r)
        {
            return l.sum > r.sum || l.sum == r.sum && (l.ch > r.ch || l.ch == r.ch && l.id < r.id);
        }); // 用 lambda 写 cmp 函数
    for (int i = 1; i <= 5; i++) // 输出前五个
    {
        cout << s[i].id << ' ' << s[i].sum << endl;
    }
    return 0;
}