AI刷题 | 豆包MarsCode AI 刷题

71 阅读3分钟

问题描述

问题描述

小F制定了一份刷题计划,她找到了一共有n套试卷,每套试卷的题目数量为a_i。她希望每天刷的题目总数是k的倍数。小F每天最多可以在上午和下午各刷一套试卷,也可以选择不刷题。现在,她需要知道最多能刷多少天的题。


测试样例

样例1:

输入:n = 5 ,k = 3 ,a = [1, 2, 3, 4, 5]
输出:1

样例2:

输入:n = 5 ,k = 3 ,a = [1, 1, 1, 1, 1]
输出:0

样例3:

输入:n = 6 ,k = 4 ,a = [3, 1, 4, 1, 5, 9]
输出:1

问题分析

本问题的目标是优化小F刷题的策略,以最大化满足以下条件的天数: 每天刷题的总数必须是 k 的倍数,且每天最多可以选择两套试卷(分别在上午和下午刷)。每套试卷的题目数是固定的,不能拆分或调整。 因此需要通过合理的试卷组合,尽可能多地满足条件,从而计算最多可以刷题的天数。

分析与思路

1. 约束条件分析

每天刷题的总数为 k 的倍数:设每天刷的两套试卷题目数为 𝑎𝑖和 a j,则必须满足: (𝑎𝑖+𝑎𝑗)%𝑘=0或者:𝑎𝑖%𝑘=0 (单独刷一套题且满足条件)。 每天最多两套试卷:小F只能从题库中选择两套试卷来满足上述条件,且选择后试卷不可重复使用。

2. 数据分类与利用

每个试卷的题目数 𝑎𝑖对k 的余数是固定的,即: remainder=𝑎𝑖%𝑘 因此,可以将试卷按余数进行分组。例如,若 k=3,题目数为 [1,2,3,4,5],则对应的余数分组为: 余数 0:[3], 余数 1:[1,4], 余数 2:[2,5]。

3. 配对策略

对于每组余数,分别处理: 余数为 0:这些试卷可以单独满足 k 倍数的条件,因此从中最多能刷: count0=size of group 0//2 天(每天刷两套)。 其他余数对:对于余数 i 和 k−i,它们可以配对使得总和为 k 的倍数。配对后从两组中尽可能多地刷题: counti =min(size of group i,size of group k−i) 特殊情况(k 为偶数):如果 i=k/2,则这一组中的试卷只能内部配对,因此从中最多能刷: countk/2 =size of group k/2//2

算法流程

统计余数分布:遍历数组 a,统计每个余数出现的次数。 计算单独满足条件的天数:处理余数为 0 的试卷。 配对满足条件的天数:处理互补余数对(如余数 1 和 k−1)。 特殊余数处理(如果 k 为偶数):处理余数为 k/2 的试卷。 返回结果:累加所有满足条件的天数。

代码实现

def solution(n: int, k: int, a: list) -> int:
    from collections import Counter

    # 统计余数出现的次数
    remainder_count = Counter(x % k for x in a)

    # 初始化可以刷题的天数
    days = 0

    # 处理余数为 0 的情况
    days += remainder_count[0] // 2

    # 处理其他余数对
    for i in range(1, (k // 2) + 1):
        if i == k - i:  # 特殊情况,余数为 k/2
            days += remainder_count[i] // 2
        else:
            days += min(remainder_count[i], remainder_count[k - i])

    return days

复杂度分析

时间复杂度

遍历试卷数组 a 时需要 O(n)。 配对时最多遍历 k 个余数组。

空间复杂度

需要一个大小为 k 的数组来存储每个余数的计数。

总结

本题通过分类和分组的方式将刷题问题转化为数学配对问题,利用余数的性质和动态统计的思想高效地计算最大刷题天数。 使用了 O(n) 的线性时间复杂度,适用于大规模数据输入。