题目地址
题目大意:给出n,k(n<=50000,k<=n),及n个x轴位置,可从这n个点中拿走k个点,求剩余点与某个点的距离平方和最小
解题思路:首先判断n是否严格大于k,若大于,则本题相当于求(Xi-X均)^2之和最小,要求得最小值贪心舍掉连续k个点
令sum为Xi的和,m为留下的Xi的个数,则X均 = sum/m
(Xi-X均)^2 = Xi^2+m*X均^2-2*Xi*X均
m个数的(Xi-X均)^2 为 ( X1^2+X2^2+......+Xm^2)+m*(sum/m)*(sum/m)-2* sum*(sum/m)→( X1^2+X2^2+......+Xm^2)+* sum*(sum/m)
将给出点按照位置从小到大排序,枚举留下的点即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4+100;
double a[maxn];
int main()
{
int t,n,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(int i = 0; i < n; i++)
scanf("%lf",&a[i]);
int m = n-k;
if(m <= 0)
{
puts("0");
continue;
}
sort(a,a+n);
double sum1 = 0;
double sum2 = 0;
for(int i = 0; i < m; i++)
{
sum1 += a[i];
sum2 += a[i]*a[i];
}
double minn = sum2-sum1*sum1/(double)m;
for(int i = m; i < n; i++)
{
sum1 -= a[i-m];
sum2 -= a[i-m]*a[i-m];
sum1 += a[i];
sum2 += a[i]*a[i];
minn = min(minn,sum2-sum1*sum1/m);
}
printf("%.10lf\n",minn);
}
return 0;
}