2020牛客NOIP赛前集训营-普及组(第五场) C题题解

T3 最少移动

https://ac.nowcoder.com/acm/contest/7612/C

显然,由题意可以发现,每一次操作之后序列总和不变。

由于需要保证每一个数相同,因此我们可以做出如下判断:令 ,如果 ( 能被 整除),那么可以达到题目要求;反之则不能达到题目要求。

下文令 表示 序列的平均数。

求最小步数时,我们发现: 只能影响 ,要使 ,只能由 操作,并且对于同一个数,+1 之后 -1 没有任何意义,所以我们从 开始,一个一个变为 ,保证 只能与 操作,到最后操作完毕时的最小步数就是答案。

代码:

#include<bits/stdc++.h>
using namespace std;

const int MAXN=1e5+10;
int n,t,a[MAXN];
typedef long long LL;
LL sum,ans;//最好开 long long

int main()
{
//    freopen(".in","r",stdin);
//    freopen(".out","w",stdout);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);ans=0;sum=0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) sum+=(LL)a[i];
        if(sum%(LL)n!=0) cout<<"-1\n";
        else
        {
            int ave=sum/n;
            for(int i=1;i<=n;i++)
            {
                ans+=abs((LL)a[i]-(LL)ave);//计算答案
                a[i+1]-=ave-a[i];//改变a[i+1],如果ave-a[i]为负数那么a[i+1]就会加上相应值
            }//这里是改变a[i],如果不理解可以手动模拟一遍
            cout<<ans<<"\n";
        }
    }
    return 0;
}
全部评论

相关推荐

10-29 18:20
济南大学 Java
用微笑面对困难:他不是人事吗,怎么净特么不干人事
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务