传送门:P1104 生日
更佳的阅读体验:洛谷 P1104 题解
简要题意:给定 $n$ 位同学的姓名和生日,要求对这些同学按年龄从大到小排序。
看到这么多信息,我们应该可以想到,使用结构体来维护每个同学的信息。
但题目要求我们,如果生日完全相同时,后输入的同学先输出。因此除了题目给出的 $s,y,m,d$ 四个变量,我们还需要在结构体中维护一个变量 $num$,用于存储该同学是第几个被输入的。
题目要求我们对每个同学按照年龄为关键字排序,但我们发现,对每个同学计算年龄是很复杂的。因此我们考虑转换思路。
可以想到,如果一个同学 $a$ 比另一个同学 $b$ 出生得更早,那么同学 $a$ 一定比同学 $b$ 更大。
接下来就可以考虑定义排序规则了。我们发现,对于两个同学 $a$ 和 $b$,$a$ 比 $b$ 先输出,当且仅当:
- 若 $y_a \neq y_b$,则 $y_a < y_b$ 时。
- 否则,若 $m_a \neq m_b$,有 $m_a < m_b$ 时。
- 否则,若 $d_a \neq d_b$,则 $d_a < d_b$ 时。
- 否则,有 $num_a > num_b$ 时。
按上述规则排序即可。
对于排序规则,下文代码中使用了重载 <
运算符,它等价于编写一个自定义排序函数。编写自定义排序函数的做法将以注释的形式给出。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n;
struct student {
string s;
int y, m, d, num;
bool operator<(const student x) const {
if (y != x.y) return y < x.y;
if (m != x.m) return m < x.m;
if (d != x.d) return d < x.d;
return num > x.num;
}
} a[N];
/* bool cmp(student a, student b) {
if (a.y != b.y) return a.y < b.y;
if (a.m != b.m) return a.m < b.m;
if (a.d != b.d) return a.d < b.d;
return a.num > b.num;
} */
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i].s >> a[i].y >> a[i].m >> a[i].d, a[i].num = i;
sort(a + 1, a + n + 1);
// sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; ++i) cout << a[i].s << '\n';
return 0;
}