生日

GitHub跳转原题关系图返回列表

把生日和输入顺序组成排序键,按年月日升序、同生日后输入在前输出姓名。

OJ: luogu

题目 ID: P1104

难度:普及-

标签:排序python

创建: 2026-06-19 10:10

更新: 2026-10-07 10:45

题意

输入若干同学的姓名和生日,按年龄从大到小输出姓名。年龄大等价于生日更早。

如果两个人生日完全相同,后输入的人先输出。

思路

这是多关键字排序。

对每个同学保存:

text
(年, 月, 日, -输入顺序, 姓名)

Python 元组会从左到右比较。年月日越小,生日越早,年龄越大;同一天生日时,输入顺序越靠后,-输入顺序 越小,也就排得越前。

排序后依次输出姓名即可。

Python 知识

  • name, year, month, day = input().split() 可以同时读取一个字符串和三个数字字段。
  • 元组天然支持多关键字排序,students.sort() 会按第 1 项、第 2 项、第 3 项依次比较。
  • 字符串字段 year/month/day 要转成 int,否则字符串比较会按字典序,不是数字大小。

参考笔记:

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/sorting_and_ordering.md

代码

python
n = int(input())

students = []
for order in range(n):
    name, year, month, day = input().split()
    students.append((int(year), int(month), int(day), -order, name))

students.sort()

for student in students:
    print(student[4])
cpp
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 105;

struct Student {
    string name;
    int year, month, day;
    int id; // 输入顺序,后输入的编号更大
} a[MAXN];

int n;

bool cmp(const Student &x, const Student &y) {
    if (x.year != y.year) {
        return x.year < y.year;
    }
    if (x.month != y.month) {
        return x.month < y.month;
    }
    if (x.day != y.day) {
        return x.day < y.day;
    }
    return x.id > y.id;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].name >> a[i].year >> a[i].month >> a[i].day;
        a[i].id = i;
    }

    sort(a + 1, a + n + 1, cmp);

    for (int i = 1; i <= n; i++) {
        cout << a[i].name << '\n';
    }

    return 0;
}

Pythonic 写法

元组排序:

python
n = int(input())
students = []
for order in range(n):
    name, y, m, d = input().split()
    students.append((int(y), int(m), int(d), -order, name))
for *_, name in sorted(students):
    print(name)

复杂度

时间复杂度为 O(nlog⁡n)O(n \log n),空间复杂度为 O(n)O(n)。

总结

多关键字排序时,先把题目的比较规则逐项写出来,再把它翻译成一个元组排序键。