1. 题目解析与问题建模
1.1 问题背景与描述
这是一个关于环形糖果传递的经典算法问题。题目描述如下:有n个小朋友围坐成一圈,每人初始有一定数量的糖果。小朋友之间可以互相传递糖果,每次传递只能发生在相邻两人之间。我们的目标是让所有小朋友最终拥有相同数量的糖果,同时使传递的糖果总数最小。
这个问题在实际生活中有很多应用场景,比如:
- 分布式系统中的负载均衡
- 生产线上物料分配的优化
- 网络流量调度中的带宽分配
1.2 数学建模
设第i个小朋友初始有a_i颗糖果,最终每人应该有avg = (∑a_i)/n颗糖果。设第i个小朋友向左传递b_i颗糖果(若b_i为负则表示向右传递),则可以建立如下方程组:
code复制a₀ - b₀ + b₁ = avg
a₁ - b₁ + b₂ = avg
...
a_{n-1} - b_{n-1} + b₀ = avg
这个环形结构的关键在于最后一个方程又回到了第一个小朋友,形成了闭环。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法思路与推导
2.1 方程组的解构
通过观察方程组,我们可以发现每个方程都可以表示为:
code复制b_{i+1} = b_i + (a_i - avg)
(这里下标按模n运算)
这个递推关系让我们可以用b₀表示所有的b_i:
code复制b_i = b₀ + Σ(a_j - avg) for j=0 to i-1
2.2 转化为中位数问题
我们的目标是最小化∑|b_i|。将b_i的表达式代入,可以发现这等价于在数轴上找一点b₀,使得它到n个特定点的距离之和最小。这些特定点是:
code复制c_i = -Σ(a_j - avg) for j=0 to i-1
根据数学理论,当b₀取这些c_i的中位数时,距离和最小。这就是著名的"中位数贪心"策略。
3. 算法实现详解
3.1 完整代码实现
cpp复制#include <bits/stdc++.h>
namespace ranges = std::ranges;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
int main() {
std::ios::sync_w
