有一瓶饮料,装着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()
浙公网安备 33010602011771号