http://acm.hdu.edu.cn/showproblem.php?pid=5073
推公式即可,质心公式segma(xi*wi)/segma(wi)
最终剩下的一定是连续n-k个星
然后枚举左边需要移除几个星即可
计算I的时候展开来算
比较坑的地方在于,星星的位置如果是int型,一定记得Double计算的时候 *1.0或者直接将位置数组声明为double 否则WA到死。。。
//#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <iomanip> #include <cmath> #include <map> #include <set> #include <queue> using namespace std; #define ls(rt) rt*2 #define rs(rt) rt*2+1 #define ll long long #define ull unsigned long long #define rep(i,s,e) for(int i=s;i<e;i++) #define repe(i,s,e) for(int i=s;i<=e;i++) #define CL(a,b) memset(a,b,sizeof(a)) #define IN(s) freopen(s,"r",stdin) #define OUT(s) freopen(s,"w",stdout) const ll ll_INF = ((ull)(-1))>>1; const double pi = acos(-1.0); const int INF = 100000000; const int MAXN = 50000+50; const double EPS = 1e-14;///// double pos[MAXN]; int n,k; double sum[MAXN],sumpos[MAXN]; double solve() { double tmp=0.0; double ans=1000000000000000000.0; if(n==k)return 0.0; for(int left=0;left<=k;left++) { tmp=sum[n-k+left]-sum[left]; double spp=sumpos[n-k+left]-sumpos[left]; double d; d=spp/(1.0*n-k); double ret=tmp-2*spp*d+(n-k)*d*d; if(left) { ans=min(ans,ret); } else ans=ret; } return ans; } int main() { //IN("hdu5073.txt"); int ncase; scanf("%d",&ncase); while(ncase--) { scanf("%d%d",&n,&k); sum[0]=0.0; sumpos[0]=0.0; for(int i=1;i<=n;i++) { scanf("%lf",&pos[i]); } sort(pos+1,pos+n+1); for(int i=1;i<=n;i++) { sum[i]=sum[i-1]+pos[i]*pos[i]; sumpos[i]=sumpos[i-1]+pos[i]; } printf("%.14lf\n",solve()); } return 0; }
时间: 2024-10-04 03:59:29