1 条题解

  • 0
    @ 2025-10-8 17:02:26

    因为是围成一个圈,假如第一个人给了第 n 个人 x1 个糖果,第二个人给了第一个人 x2 个糖果,.....第 n 个人给了第 n - 1 个人 xn 个糖果。(xi可以为负数)

    答案就是 abs(x1) + abs(x2) + abs(x3) + ..... + abs(xn)

    最终每个人的糖果数 avg 等于 总糖果数 sum 除以人数 n,即 avg=sum/n

    对于第一个人来说有:

    a[1] - x1 + x2 = avg;

    依次列出有:

    a[2] - x2 + x3 = avg;

    a[3] - x3 + x4 = avg;

    ....

    化简一下有

    x2 = x1 + avg - a[1] = x1 - (a[1] - avg);

    x3 = x2 + avg - a[2] = x1 - (a[1] - avg) - (a[2] - avg);

    ......

    我们让

    c[1] = a[1] - avg;

    c[2] = (a[1] - avg) + (a[2] - avg);

    ......

    最终的答案就为 abs(x1) + abs(x1 - c[1]) + abs(x1 - c[2]) ..... + abs(x1 - c[n - 1])

    (i = x1 - c[i - 1])

    观察可得,当对 c[i] 排序,取 t 为其中间点时,答案最小。

    #include<bits/stdc++.h> 
    using namespace std;
    typedef long long LL;
    const int N=1e6+10;
    LL a[N], c[N];
    int main()
    {
        int n; scanf("%d",&n);
        LL sum=0;  for(int i=1; i<=n; i++) scanf("%lld", &a[i]), sum+=a[i];
        LL avg=sum/n; 
        c[0]=0;for(int i=1; i<=n; i++) c[i]=c[i-1]+(a[i]-avg);
        sort(c+1, c+n+1);
        LL t=c[(n+1)/2], ans=0;
        for(int i=1; i<=n; i++) ans+=abs(t-c[i]);
        printf("%lld\n", ans);
        return 0;
    }
    
    • 1

    A31 贪心算法【中位数进阶】行循环均分[HAOI2008] 糖果传递

    信息

    ID
    2698
    时间
    1000ms
    内存
    128MiB
    难度
    3
    标签
    递交数
    107
    已通过
    57
    上传者