蓝桥杯-奖学金问题
题目描述
某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 5 名学生发奖学金。期末,每个学生都有 3 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。
任务:先根据输入的 3 门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前 5 名学生的学号和总分。注意,在前 5 名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分)是:
7 279
5 279
含义是:总分最高的两个同学的学号依次是 7 号、5 号。这两名同学的总分都是 279 (总分等于输入的语文、数学、英语三科成绩之和),但学号为 7 的学生语文成绩更高一些。
解题过程
看到题目就想起结构体,但昨天用了python的字典,觉得可以代替C的结构体,就尝试了一下:
n=int(input())
st={}
for i in range(n):
st[i]=list(map(int,input().split(' '))) #学号当作key
st[i].append(st[i][0]+st[i][1]+st[i][2]) #计算总分
result=sorted(st.items(),key=lambda x:(x[1][3],x[1][0],x[0]),reverse=True)
#按总分, 按语文,按学号
#print(st)
print(result)
for i in range(5):
print(str(result[i][0]+' '+str(st[i][1][3])))
盲点:字典排序
sorted(st.items(),key=lambda x:(x[1][3],x[1][0],x[0]),reverse=True)
key就是排序的依据
输出排序之前的st:
print(st)
>>{0: [90, 67, 80, 237], 1: [87, 66, 91, 244], 2: [78, 89, 91, 258], 3: [88, 99, 77, 264], 4: [67, 89, 64, 220], 5: [78, 89, 98, 265]}
所以lambda x 就是一条元组形式的记录:
print(st.items())
>>dict_items([(0, [90, 67, 80, 237]), (1, [87, 66, 91, 244]), (2, [78, 89, 91, 258]), (3, [88, 99, 77, 264]), (4, [67, 89, 64, 220]), (5, [78, 89, 98, 265])])
如:(5, [78, 89, 98, 265])
**x[1]:**元组的第二个值,存分数的列表:[78,89,98,265]
x【1】【3】:列表的第四个元素,总分
x[0]:,元组的第一个值,学号
sorted()排好序后返回的是列表
print(result)
>>[(5, [78, 89, 98, 265]), (3, [88, 99, 77, 264]), (2, [78, 89, 91, 258]), (1, [87, 66, 91, 244]), (0, [90, 67, 80, 237]), (4, [67, 89, 64, 220])]
总结:
sorted(可迭代对象,key=函数名,reverse=False/True)
#reverse默认等于False,从小到大排序。等于True时,从大到小排序
-
sorted函数中的可迭代对象不要用字典d,那样只能迭代出的字典d的键。要用d.items()才可迭代出字典的键值对。
-
sorted函数排好序后,要赋值给一个对象(返回了一个列表)