这道题定义类,并且在类中定义方法写,这样思路更清晰点
from functools import cmp_to_key
# 定义Student类,用于表示学生信息
class Student:
def __init__(self, student_id: str):
# 初始化学生ID
self.id = student_id
# 初始化成绩数组,长度为k + 1,初始值为-2(表示从未提交过代码的状态)
self.grade = [-2] * (k + 1)
# 初始化总成绩和满分成绩数量
self.total = 0
self.cnt = 0
def calc(self):
# 计算总成绩(只计算非负成绩),因为grade[i] = -1代表未编译通过的状态,分数记为0
for i in range(1, k + 1):
self.total += max(0, self.grade[i])
for i in range(1, k + 1):
if self.grade[i] == p_score[i - 1]: # p_score[i]存的是i + 1的问题满分数据,所以p_score[i - 1]存的是i问题的满分数据
self.cnt += 1
def has_submit(self):
# 检查学生是否有提交的成绩
for i in range(1, k + 1):
if self.grade[i] >= 0:
return True
return False
# 初始化学生字典
students = {}
# 读取学生数量n、科目数量k和提交数量m
n, k, m = map(int, input().split())
# 读取每科的满分成绩
p_score = list(map(int, input().split())) # p 代表perfect adj.完美的
# 循环读取每个学生的提交信息
for _ in range(m):
# 读取学生ID、科目ID和成绩
u_id, p_id, grade = input().split()
p_id, grade = int(p_id), int(grade)
# 如果学生不在字典中,则添加新学生
if u_id not in students:
students[u_id] = Student(u_id)
# 更新学生的成绩(取最高分)
students[u_id].grade[p_id] = max(students[u_id].grade[p_id], grade)
# 初始化结果列表
res = []
# 遍历学生字典,筛选出有提交的学生并计算其成绩
for s in students.values():
if s.has_submit(): # 如果该学生有提交过代码,则计算他的总分和满分数量,并将该学生添加到res列表中
s.calc()
res.append(s)
def cmp(lhs: Student, rhs: Student):
if lhs.total < rhs.total:
return 1
elif lhs.total == rhs.total and lhs.cnt < rhs.cnt:
return 1
elif lhs.total == rhs.total and lhs.cnt == rhs.cnt and lhs.id > rhs.id:
return 1
else:
return -1
# 对结果列表进行排序(按总成绩、满分成绩数量、学生ID排序)
res.sort(key=lambda x: (-x.total, -x.cnt, x.id))
# res.sort(key=cmp_to_key(cmp)) 这两行代码等价
# 初始化排名
rank = 1
# 遍历结果列表并打印输出
for i, s in enumerate(res, start=1):
# 如果当前学生的总成绩与前一个学生的总成绩不同,则更新排名
if i - 1 > 0 and res[i - 1].total != res[i - 2].total:
rank = i
# 打印学生信息(排名、ID、总成绩、各科成绩)
print(f"{rank} {s.id} {s.total}", end='')
for grade in s.grade[1:]: # 注意:grade从索引1开始,因为索引0未使用
if grade == -2:
print(' -', end='')
elif grade == -1:
print(' 0', end='')
else:
print(f' {grade}', end='')
print()