Python入门习题(71)——OpenJudge百练习题:GPA排名系统

OpenJudge百练第4043号习题:GPA排名系统

  • 题目描述
  • 解题思路
  • 参考答案
  • 测试用例
  • 小结

题目描述

来源
OpenJudge网站 – 百练习题集-第4043号习题

要求
总时间限制: 1000ms 内存限制: 65536kB

描述

目前,高等院校往往采用GPA来评价学生的学术表现。传统的排名方式是求对每一个学生的平均成绩,以平均成绩作为依据进行排名。
但这样的排名方法已经引起了教育界以及社会各界人士的争议,因为它存在着许多弊端。对于不同的课程,选课学生的平均成绩会不同程度地受到课程的难易程度和老师的严厉程度的制约。因而这样的排名系统无形中就鼓励了学生选择一些比较容易的课程,因为这样可以事半功倍地获得较高的平均分。
为了克服这些弊端,需要对排名系统做一定的改进。
一种改进的方案是对选第i门课的每一个学生的成绩加上一个特定的修正值di,例如编号为j的学生该课的成绩Gij修改为G’ij=Gij+di。最终使得经过调整后,该课调整后的平均分等于未调整前选该课的所有学生所有课的平均分。你的任务是根据某一个班级学生某学期的成绩,计算每门课的修正值di。
输入学生人数m(1 <= m <= 20)、课程数目n(1 <= n <= 10)、课程名称以及各个学生各门课的成绩。对于第i门课程,输出修正值di。

输入

  1. 第一行输入两个整数,用空格分隔,分别为学生人数m和课程数目n。
  2. 第二行输入n门课程名称,用空格分隔。每门课程的名称均不超过15个字符,均为小写。
  3. 第三行开始输入m * n的矩阵。表示各个学生各门课成绩x(0 < x <= 100),以空格分隔。若学生未选此课,则该位输出0.

输出
输出为n行,每行格式为“math 5”。首先输出课程名称,空格后输出修正值di。di为整数(计算过程中小数部分均舍去,不考虑),若di为正,符号输出‘’,否则输出‘-’

样例输入
8 5
math physics algebra english chemistry
98 78 0 76 86
0 79 99 89 68
0 0 79 96 78
58 97 79 90 47
90 0 84 99 77
94 54 76 85 0
69 60 0 85 95
79 85 86 96 68
样例输出
math -1
physics 4
algebra -2
english -8
chemistry 7

解题思路

  1. 求出各个学生的总分,存在sum_stu_scores列表中。
  2. 求出各个学生的修课门数,存在count_stu_courses列表中。由于学生修课门数不同,求平均的时候要用到学生的修课门数这个数据。
  3. 对于每一门课,
    (3-1)求出修这门课的学生的累计得分和累计人数,得到平均分avg_course。
    (3-2)求出修这门课的学生的所有课的累计总分和累计修课门数,得到平均分avg_all_courses。
    (3-3)avg_all_courses减去avg_course就是这门课的修正值。

参考答案

stu_num, course_num = [int(s) for s in input().split()]
course_names = input().split()
stu_scores = [[int(s) for s in input().split()] for i in range(stu_num)]

#各个学生的总分
sum_stu_scores = [sum(stu_score) for stu_score in stu_scores]
#各个学生的修课门数
count_stu_courses = [course_num - stu_score.count(0) for stu_score in stu_scores]

for column in range(course_num):
    sum_course = 0  #本门课程的合计分数
    sum_all_courses = 0  #修本课的所有学生的所有课程的总分
    count_course = 0  #修本门课程的人数
    count_all_courses = 0  #修本课的所有学生的修课门数合计
    for row in range(stu_num):
        if stu_scores[row][column] > 0:
            count_course += 1
            sum_course += stu_scores[row][column]
            sum_all_courses += sum_stu_scores[row]
            count_all_courses += count_stu_courses[row]
    avg_course = sum_course // count_course
    avg_all_courses = sum_all_courses // count_all_courses
    # print(course_names[column], "avg: ", avg_course)
    print(course_names[column], avg_all_courses - avg_course )

测试用例

  1. 题目描述给出的测试用例覆盖了没有选某门课的情形。

  2. 有两位同学没有选math这门课,把这两位同学的两行成绩去掉,math的修正值不发生变化,也就是说与题目描述给出的样例输出中的值相同,都为-1。这样能证明程序正确处理了没修课的情形。
    样例输入
    6 5
    math physics algebra english chemistry
    98 78 0 76 86
    58 97 79 90 47
    90 0 84 99 77
    94 54 76 85 0
    69 60 0 85 95
    79 85 86 96 68
    样例输出
    math -1
    physics 5
    algebra -1
    english -8
    chemistry 7

  3. n=1的边界情形。修正值应该等于0。
    样例输入
    8 1
    math
    98
    0
    0
    58
    90
    94
    69
    79
    样例输出
    math 0

  4. m=1, n=1的边界情形。修正值应该等于0。
    样例输入
    1 1
    math
    98
    样例输出
    math 0

  5. 拿容易计算的数据测一遍。
    样例输入
    3 2
    math physics
    60 80
    60 80
    60 80
    样例输出
    math 10
    physics -10

小结

  1. 要读懂题目描述中的这句话,“最终使得经过调整后,该课调整后的平均分等于未调整前选该课的所有学生所有课的平均分。”
  2. 不能拿学生的平均分合计除以学生人数来计算学生所有课的平均分,因为不同学生的修课门数可能不同。一句话,没修这门课就不参与求平均。

你可能感兴趣的:(Python入门100道习题,Python编程)