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; }