Hdu 5073 Galaxy 精度问题

 

  思路: 其实求解很简单直接说解法,移动K个后 上下的角动量最小,能肯定是相连的(n-k)个,至于为什么 你自己好好想想(easy);

     对于一些等质量的质点中心在 所在位置和除以点的个数

     average=sum[l,l+(n-k)-1]/(n-k);

      一个点的值: (pi-average)* (pi-average)

      也就是 pi^2+avery^2 - 2*pi*average  

      多个点相加也就是 ∑pi^2+(n-k)*sum*sum/(n-k)/(n-k)   -  2*∑pi*sum/(n-k);

            =   ∑pi^2+(n-k)*sum*sum/(n-k)/(n-k)   -  2*sum*sum/(n-k);

            =   ∑pi^2   -  sum*sum/(n-k);

     所以要处理一下 ”普通和“,“平方和” 就好了

     但是这个卡精度:我的做法  每次比较   (n-k)*∑pi^2   -  sum*sum

     剩下最小的 再除以(n-k) 就好了

代码.cpp

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
#include <set>
#include <cstring>
using namespace std;
typedef  long long LL;
LL p[50005];
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i = 1; i<=n; i++)scanf("%I64d",p+i);
        if(n==k||k==n-1)
        {
            printf("%d\n",0);
            continue;
        }
        sort(p+1,p+n+1);
        LL sum = 0;
        LL SUM = 0;
        for(int i = 1; i<=n-k; i++)
        {
            sum += p[i];
            SUM += p[i] * p[i];
        }
        LL need=n-k;
        LL min_ans = need*SUM - sum*sum;
        for(int i = n-k+1,j=1; i <= n; i++,j++)
        {
            sum = sum + p[i] - p[j];
            SUM = SUM + p[i]*p[i] - p[j]*p[j];
            LL now  = need*SUM - sum*sum;
            min_ans=min(min_ans,now);
        }
        //LL tmp=min_ans/need;
       // double t=min_ans%need;
       // double ans=tmp+t/(double)need;
        printf("%.11f\n",(double)min_ans/(double)need);
    }
    return 0;
}

  

 

posted @ 2014-10-22 18:04  默默无语敲代码  阅读(747)  评论(0编辑  收藏  举报