糖果传递

糖果传递题解

有n个小朋友坐成一圈,每人有a[i]个糖果。

每人只能给左右两人传递糖果。

每人每次传递一个糖果代价为1。

求使所有人获得均等糖果的最小代价。

输入格式

第一行输入一个正整数n,表示小朋友的个数。

接下来n行,每行一个整数a[i],表示第i个小朋友初始得到的糖果的颗数。

输出格式

输出一个整数,表示最小代价。

数据范围

1≤n≤1000000

输入样例:
4
1
2
5
4
输出样例:
4

分析:

多个考点综合的问题,感觉像一道数学题。

对于每个人,假设他的糖果数要经过两类变化:1、从后一个人拿。2、给前一个人

最终的变化结果是变为ave。

所以有

  • a[1]-X1+X2=ave X2=X1-(a[1]-ave)
  • a[2]-X2+X3=ave X3=X1-(a[2]+a[1]-2*ave)

设c[1]=a[1]-ave

c[2]=c[1]+a[2]-ave

则有c[i]=c[i-1]+a[i]-ave

则有问题|X1|+|X2|+……+|Xn|的和最小每个都可以用X1表示为

|X1|+|X1-c[1]|+|X2-c[2]|+……+|X1-c[n-1]|

绝对值的含义又可以表示数轴上Xi到Ci的距离

所以问题转化为在c[1]到c[n-1]中选一个点到所有点的距离的和最短

(即中位数)

注意:不应该加上abs(c[n]-c[mid]),并且ans最后应该加上mid

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N=1e6+5;

int a[N],c[N];

int main()
{
	int n;
	cin>>n;
	LL sum=0;//记得初始化为0
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum+=a[i];
	}
	
	int ave=sum/n;
	
	for(int i=1;i<n;i++)
	{
		c[i]=c[i-1]+a[i]-ave;
	}
	
	sort(c+1,c+n);//c[0]=0不能参与排序影响结果
	
	LL ans=0;
	int pos=n>>1;
	for(int i=1;i<n;i++)
	{
		ans+=abs(c[pos]-c[i]);
	}
	
	ans+=abs(c[pos]);
	cout<<ans<<endl;
	return 0;
}

3.11

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥羊也

感谢给肥羊投喂!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值