SSLOJ 1440.能量传输【思维】


题目:

传送门


题意:

给出 n n n个人的能量,间隔为 k k k的两个人才能传递能量,问最少要用多少次才能使所有人的能量相等


分析:

我们可以与洛谷上的糖果传递进行类比,那道题的间隔是 0 0 0,但在这里是 k k k
所以我们可以以 i i i这个点开始暴力求出一个环,环上的点都恰好间隔为 k k k,这样一来单独看环的话每个点的间隔都是 0 0 0
我们就直接按照糖果传递的方法来跑


代码:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
#define LL long long 
using namespace std;
inline LL read() {
    
    
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){
    
    if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){
    
    d=d*10+s-'0';s=getchar();}
    return d*f;
}
LL tf[500005],x[500005],y[500005],a,xx[500005];
int main()
{
    
    
	LL n=read(),k=read()+1,ans=0;
	for(LL i=1;i<=n;i++) x[i]=read(),a+=x[i];
	a/=n;
	for(LL i=1;i<=n;i++)
	{
    
    
		if(tf[i]) continue;
		LL len=0,j=i;
		while(!tf[j])
		{
    
    
			tf[j]=1;y[++len]=x[j];j+=k;
			j=(j-1)%n+1;
		}
		for(LL i=1;i<=len;i++) xx[i]=xx[i-1]+y[i]-a;
		sort(xx+1,xx+1+len);
		LL e;
		if(len&1) e=xx[len/2+1];
		else e=(xx[len/2]+xx[len/2+1])/2;
		for(LL i=1;i<=len;i++) ans+=abs(xx[i]-e);
	}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/103056462
今日推荐