100. 统计班级中的说谎者 | 豆包MarsCode AI刷题

83 阅读3分钟

详细解析 问题背景 假设有一个班级,班里的每个学生都有一个成绩。根据题目要求,如果一个学生发现成绩低于或等于自己成绩的同学比成绩高于自己的同学多,那么这个学生就会被认为是在说谎。任务是编写一个函数来计算班里有多少学生会说谎。

核心逻辑 成绩分布统计:首先需要了解每个成绩有多少个学生取得了这个成绩。 排序处理:对成绩进行排序,以便能够从最低分开始逐步向上累加。 动态计算:随着成绩的增加,动态地计算成绩低于或等于当前成绩的学生数和成绩高于当前成绩的学生数。 判断条件:每当成绩低于或等于当前成绩的学生数超过成绩高于当前成绩的学生数时,当前成绩的所有持有者都被认为是在说谎。


from collections import Counter

def solution(A):
    # Step 1: 使用Counter统计每个成绩出现的次数
    count = Counter(A)  # 这里创建了一个字典,键是成绩,值是该成绩出现的次数
    
    # Step 2: 将成绩和出现次数按照成绩从小到大排序
    sorted_scores = sorted(count.items())  # items()方法返回的是一个元组列表,每个元组包含成绩和它的出现次数
    
    # Step 3: 初始化一些变量
    total_students = len(A)  # 班级中的总学生数
    cumulative_less_equal = 0  # 累积小于等于当前成绩的学生数
    liars = 0  # 说谎的学生数
    
    # Step 4: 遍历排序后的成绩列表
    for score, freq in sorted_scores:  # 分别获取成绩(score)和它出现的次数(freq)
        cumulative_less_equal += freq  # 累加当前成绩及以下的学生数
        greater = total_students - cumulative_less_equal  # 计算成绩高于当前成绩的学生数
        
        # Step 5: 判断是否说谎
        if cumulative_less_equal > greater:  # 如果成绩小于等于当前成绩的学生数大于成绩高于当前成绩的学生数
            liars += freq  # 当前成绩的所有持有者都被认为是在说谎
    
    # Step 6: 返回说谎的学生数
    return liars

# 测试代码
if __name__ == "__main__":
    # 测试用例1:所有学生都取得了最高分,因此所有人都会说谎
    print(solution([100, 100, 100]) == 3)
    
    # 测试用例2:两个较低分的学生会说谎,因为他们认为自己不是最低分
    print(solution([2, 1, 3]) == 2)
    
    # 测试用例3:成绩为1的学生和成绩为30的三个学生会说谎
    print(solution([30, 1, 30, 30]) == 3)
    
    # 测试用例4:成绩为19、27、73的学生会说谎
    print(solution([19, 27, 73, 55, 88]) == 3)
    
    # 测试用例5:成绩为19、27、73、88的学生会说谎
    print(solution([19, 27, 73, 55, 88, 88, 2, 17, 22]) == 5)
    

关键点解释 Counter对象:Counter 是 collections 模块中的一种容器,它是一个字典子类,用来计数可哈希对象。在这里,我们使用它来快速统计每个成绩出现的次数。 排序:通过 sorted() 函数对成绩进行排序,确保我们可以从最低分开始累加学生数。 累积计算:通过一个变量 cumulative_less_equal 来累积计算成绩小于等于当前成绩的学生数。 说谎条件:通过比较成绩小于等于当前成绩的学生数和成绩高于当前成绩的学生数,来判断当前成绩的所有持有者是否会说谎。 测试用例:通过几个测试用例来验证算法的正确性,确保我们的逻辑没有错误