Uva Galaxy(尺取法)

题意:n颗行星,给出每个点的一维坐标,可以删去m个点,使剩下所有点到剩余点集中心的距离的平方的和最小,求该最小值;

思路:尺取法,每次维护n-m个点;long long用%lld读入,但codeblocks编译会出现问题,所以用cin>>;

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int t,n,m;
long long s1,s2;
long long num[50500];
double sum,mid,cnt;
int main()
{
    int i,j,k,l,r;
    scanf("%d",&t);
    while(t--){
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++){
        scanf("%lld",&num[i]);
      }
      if(n==m){
        printf("0\n");
        continue;
      }
      sort(num+1,num+n+1);
      s1=0;s2=0;cnt=0;
      for(i=1;i<=n-m;i++){
         s1+=num[i];
         s2+=num[i]*num[i];
      }
      mid=s1*1.0/(n-m);
      cnt=s2+(n-m)*mid*mid-2*mid*s1;
      for(i=1;i<=m;i++){
        s1=s1-num[i]+num[n-m+i];
        s2=s2-num[i]*num[i]+num[n-m+i]*num[n-m+i];
        mid=s1*1.0/(n-m);
        double temp=s2+(n-m)*mid*mid-2*mid*s1;
        if(temp<cnt){
          cnt=temp;
        }
      }
      printf("%.10f\n",cnt);
    }
    return 0;
}

 

posted @ 2015-09-01 13:02  dominating大树置林  Views(119)  Comments(0)    收藏  举报