[NOIP 2007 普及组] 奖学金

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

把学生保存为记录,按总分降序、语文降序、学号升序排序后输出前五名。

OJ: luogu

题目 ID: P1093

难度:入门

标签:排序模拟python

日期: 2026-06-19 01:35

题意

每个学生有语文、数学、英语三科成绩。先计算总分,再按总分高、语文高、学号小的顺序排序,输出前五名的学号和总分。

思路

每个学生保存为:

python
(student_id, total, chinese)

排序规则可以直接写成 key 元组:

python
(-total, -chinese, student_id)

总分和语文要降序,所以加负号;学号要升序,直接使用原值。

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/sorting_and_ordering.md:多关键字排序可以用元组 key
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:每行三个整数用 map(int, input().split())
  • students[:5] 取排序后的前五名。

代码

python
n = int(input())
students = []

for student_id in range(1, n + 1):
    chinese, math, english = map(int, input().split())
    total = chinese + math + english
    students.append((student_id, total, chinese))

students.sort(key=lambda student: (-student[1], -student[2], student[0]))

for student in students[:5]:
    print(student[0], student[1])

Pythonic 写法

多关键字 sort:

python
n = int(input())
students = []
for sid in range(1, n + 1):
    c, m, e = map(int, input().split())
    students.append((- (c + m + e), -c, sid, c + m + e))
for _, _, sid, total in sorted(students)[:5]:
    print(sid, total)

复杂度

排序 n 名学生,时间复杂度 O(nlogn)O(n\log n),空间复杂度 O(n)O(n)

总结

排序题最重要的是把关键字顺序写对。降序字段取负,升序字段保持原值,是 Python 多关键字排序的常用写法。