题解CF1106C
本题应该降橙
CF1106C题目传送门
题意简述
给你 个数,求这些数分组后平方和的最小值。
一组至少要有 个数。
题目保证 是偶数。
思路
这个问题我们需要证明一个点:
:一个排好序后的数组,分组后平方和的最小值一定是让 和 相加。
众所周知,在 的情况下, 。
所以我们让 尽可能的小?
不是的。
因为一个 的数组,按这种方式答案是 。
然而,实际的解是 。
所以,我们让 尽可能平均。
为什么要平均呢?
看这个例子就知道了:
再到 就不用说了,肯定更大。
所以,分成任意组,极差越大,答案越大。
而我们求的是最小,所以我们应该让它平均分。
而为了平均分,我们需要使用时间复杂度为 的 排序。
当然,手打快排,归并等时间复杂度为 的排序也没有问题,但不能用 的排序,因为会 。
最后,还有 的桶排序代码,可以过 。
(正常 能过本题 ,但过不了 )
ctjer 最喜欢的代码环节
AC Code 1:
#include<iostream>
#include<algorithm>
using namespace std;
int a[300001],n;
long long ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n/2;i++){
ans+=(a[i]+a[n-i+1])*(a[i]+a[n-i+1]);
}
cout<<ans;
return 0;
}
AC Code 2:
#include<iostream>
#include<algorithm>
using namespace std;
int a[300001],x,n,b[10001],p;
long long ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>x;
b[x]++;
}
for(int i=1;i<=10000;i++){
for(int j=1;j<=b[i];j++){
a[++p]=i;
}
}
for(int i=1;i<=p/2;i++){
ans+=(a[i]+a[n-i+1])*(a[i]+a[n-i+1]);
}
cout<<ans;
return 0;
}
感谢各位在评论区 的大佬们~

浙公网安备 33010602011771号