有一瓶饮料,装着N升(N≤1e6,正整数)香槟,单次可倒出的液体必须是自然数升。有M个杯子,每个杯子里装着m_i(m_i≤1e5,正整数)升香槟。现在请你按杯子顺序i从0到M-1依次倒完饮料中的香槟,使得最终所有杯子中液量的方差最小。

输入格式

第一行:用空格隔开,N M

第二行:用空格隔开,序号0到M-1的m_i

输出格式

按0到M-1顺序,每个杯子需要添加的香槟升数,用空格隔开。

参考解法

思路是贪心+最小堆,让最小和最大数趋近。正如高中学过的完全平方式子,两个数越接近,它们的平方和越小,这也可以推广到多个数。做法如下:

1. 从标准输入读取 N M和m_0, m_1, ..., m{M-1}

2. 使用最小堆(priority-queue)把每次1升倒入当前液量最少的杯子。

3. 输入每个杯子需要额外倒入的香槟升数x_i。

import sys
import heapq

def main() -> None:
    data = sys.stdin.read().strip().split()
    if not data:
        return

    # 读取 N, M
    N = int(data[0])
    M = int(data[1])

    # 读取 m_i
    m = list(map(int, data[2:2 + M]))
    if len(m) != M:
        # 输入不合法,直接退出
        return

    # 最小堆:元素为 (当前液量, cup_index)
    heap = [(m[i], i) for i in range(M)]
    heapq.heapify(heap)

    # 用于记录每个杯子额外倒入的升数
    add = [0] * M

    # 逐升倒入
    for _ in range(N):
        level, idx = heapq.heappop(heap)   # 取出当前液量最小的杯子
        add[idx] += 1                       # 倒 1 升
        heapq.heappush(heap, (level + 1, idx))  # 更新后重新放回堆

    # 按顺序输出结果
    out = ' '.join(str(add[i]) for i in range(M))
    sys.stdout.write(out)

if __name__ == "__main__":
    main()

posted on 2025-12-12 00:48  快乐的乙炔  阅读(0)  评论(0)    收藏  举报  来源