题解:P1093 [NOIP2007 普及组] 奖学金
题解:P1093 [NOIP2007 普及组] 奖学金
思路
这道题可以用结构体排序的方法做。
什么是结构体?
结构体(struct),可以看做是一系列称为成员元素的组合体。
可以看做是自定义的数据类型。
(以上摘自 OI-Wiki)
如果有些数据可以放在一起使用(如本题中一个学生的语数英三科放在一起排序),此时可以用结构体。
怎么定义结构体?
struct abc
{
int a, b, c;
};
定义了一个结构体 abc,它的每个变量都拥有 a、b、c 三个成员。
怎么定义一个结构体类型的变量?
和普通变量一样。
abc x, y = {3, 4}, *p, *q = &x, a[100] = {{0}};
这段代码定义了 abc 类型的两个变量(x 和 y)、两个指向 abc 类型变量的指针(p 和 q)、一个 abc 类型的数组。
abc y = {3, 4} 表明初始化 y 的 a 成员为 3、b 成员为 4。
怎么使用这个结构体变量?
可以用 y.c 来表示 y 的 c 成员。下面是一些例子:
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;
}