1 条题解

  • 0
    @ 2025-12-16 20:30:57

    一、题目核心含义解析

    题目要求根据N个学生的正确回答,计算课室里最少的学生总数。核心逻辑:

    • 每个学生回答的A[i] = 同姓氏但排除自己的人数 → 该学生所属姓氏的总人数 = A[i] + 1
    • 目标是通过合理分配这些学生到不同姓氏组,使得总人数最少(每个姓氏组人数固定为A[i]+1,需尽可能让每组装满以减少组数)。

    二、参考代码的核心逻辑

    代码通过数组统计次数 + 分情况计算组数贡献 实现,核心思路:

    1. 用数组b[1000005]统计每个回答值x的出现次数(因A[i]≤1e6,数组大小覆盖所有可能值)。
    2. 遍历所有可能的回答值x
      • 若该值出现次数b[x]≤x+1:只需1个姓氏组,贡献x+1人。
      • b[x]>x+1:先算完整装满的组数(b[x]/(x+1)),贡献b[x]/(x+1)*(x+1);若有余数,需额外1组,再加x+1
    3. 累加所有贡献得到最少总人数。

    三、代码逐行详细解释

    四、样例解析(贴合代码逻辑)

    样例1

    输入:4 1 2 1 2 步骤1:统计次数

    • b[1] = 2(回答值1出现2次),b[2] = 2(回答值2出现2次),其余b[i]=0

    步骤2:遍历计算贡献

    • 处理i=1b[1]=2i+1=22≤2s += 2(s=2)。
    • 处理i=2b[2]=2i+1=32≤3s +=3(s=5)。
    • 其余ib[i]=0,无贡献。 最终s=5,与样例输出一致。

    样例2

    输入:9 2 2 44 2 2 2 444 2 2 步骤1:统计次数

    • b[2]=7b[44]=1b[444]=1,其余b[i]=0

    步骤2:遍历计算贡献

    • 处理i=2b[2]=7i+1=37>3。 完整组数:7/3=2 → 贡献2×3=6(s=6); 余数7%3=1≠0 → 再加3(s=9)。
    • 处理i=44b[44]=1i+1=451≤45s +=45(s=54)。
    • 处理i=444b[444]=1i+1=4451≤445s +=445(s=499)。 最终s=499,与样例输出一致。

    五、代码逻辑与“向上取整”的等价性

    代码中对b[x]>x+1的处理,等价于“向上取整b[x]/(x+1) × x+1”:

    • 向上取整公式:groups = (b[x] + (x+1) -1) // (x+1)
    • 代码逻辑:groups = b[x]/(x+1) + (b[x]%(x+1)!=0 ? 1 : 0)。 两者结果完全一致,例如:
    • b[x]=7, x+1=3: 向上取整:(7+3-1)//3=9//3=3 → 贡献3×3=9; 代码逻辑:7/3=2 + 余数1→加1 → 组数3 → 贡献9。

    六、代码优势与适用场景

    1. 优势:
      • 用数组统计次数,时间复杂度O(N + 1e6),对于N≤50、1e6的遍历量,效率极高(1秒内可完成)。
      • 逻辑直观,分情况处理,无需复杂的向上取整公式,易理解。
    2. 适用场景:
      • 完全匹配题目中A[i]≤1e6的约束,数组大小足够覆盖所有可能的回答值。
      • 适合编程入门者理解,无复杂数据结构(如Counter),纯基础数组操作。

    七、边界情况测试

    测试用例(回答值为0)

    输入:3 0 0 0 步骤:

    • b[0]=3i+1=13>1。 完整组数:3/1=3 → 贡献3×1=3;余数0 → 无需额外加。 总人数=3(3个学生各属不同姓氏,每个姓氏仅1人)。 输出:3(符合逻辑)。

    测试用例(余数为0)

    输入:6 2 2 2 2 2 2 步骤:

    • b[2]=6i+1=36>3。 完整组数:6/3=2 → 贡献2×3=6;余数0 → 无需额外加。 总人数=6(2个姓氏组,每组3人)。 输出:6(符合逻辑)。

    信息

    ID
    2357
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    (无)
    递交数
    90
    已通过
    38
    上传者