题目描述
给一个长度为 n 的正整数序列
a
1
,
a
2
,
.
.
.
,
a
n
{a_1,a_2,...,a_n}
a1,a2,...,an,每次操作可以选择两个相邻的位置,让一个元素
−
1
-1
−1另一个元素
+
1
+1
+1,输出最少几次操作,能让所有元素相等,如果不可能实现,请输出
"
−
1
"
"-1"
"−1",不含引号。
输入描述:
第一行一个整数
T
(
T
≤
20
)
T(T≤20)
T(T≤20),表示 T 组数据。
每组数据第一行一个整数 n,第二行 n 个数字表示 a 序列, 1 ≤ a [ i ] ≤ 100000 1≤a[i]≤100000 1≤a[i]≤100000
输出描述:
对于每组数据,输出一个整数表示答案。
示例1
输入
3
3
1 3 2
3
2 2 3
5
1 2 3 1 3
输出
1
-1
3
说明
保证
T
≤
20
T≤20
T≤20
- 10% 的测试数据, 1 ≤ n ≤ 5 1≤n≤5 1≤n≤5
- 20% 的测试数据 1 ≤ n ≤ 100 1≤n≤100 1≤n≤100
- 50% 的测试数据, 1 ≤ n ≤ 1 0 3 1≤n≤10^3 1≤n≤103
- 80% 的测试数据, 1 ≤ n ≤ 1 0 4 1≤n≤10^4 1≤n≤104
- 100% 的测试数据, 1 ≤ n ≤ 1 0 5 1≤n≤10^5 1≤n≤105
解题思路
首先,我们知道,相邻两个数,一个
+
1
+1
+1,一个
−
1
-1
−1,不会让总和
(
s
u
m
)
(sum)
(sum)发生变化。所以,最终所有数的值应该是
s
u
m
/
n
sum/n
sum/n。
然后请开始贪心。。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<cmath>
using namespace std;
long long t,n,sum,ans,a[200000],v[200000];
int main(){
scanf("%lld",&t);
while(t--)
{
memset(v,0,sizeof(v));
ans=0,sum=0;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum+=a[i];
}
if(sum%n!=0)
{
printf("-1\n");
continue;
}
sum=sum/n;
for(int i=1;i<=n;i++)
{
ans+=abs(sum-a[i]);
a[i+1]=a[i+1]-sum+a[i];
}
printf("%lld\n",ans);
}
}