hdu 5073 Galaxy /2014鞍山现场赛D题

题意:

      给你n个星球,现在能移动k个星球到任意地方,求移动之后的I= sum(di*di) (i=1,2,3..,n), di为星球i到重心的距离

方法:

    我们可以很容易想到不会移动的n-k个星球一定会是连续的,然后我们枚举这连续的n-k星球即可,设移动前星球i的位置为ci, ai为ci的前i项和,bi为ci前i的平方和

则我们可以快速算出移动之后的I

PS:

 di is the distance form star i to the mass of center.  我当时以为是重心,然后这题就被我想的复杂了。

di是i到重心的距离。。。。

 

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 55555
#define eps 1e-12
int c[maxn];
double a[maxn], b[maxn];

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n, k;
		scanf("%d %d",&n,&k);
		memset(a, 0, sizeof a);
		memset(b, 0, sizeof b);
		int num;
		for(int i= 1; i<= n; i++)
			scanf("%d",&c[i]);
		sort(c+1, c+n+1);
		for(int i= 1; i<= n; i++)
		{	
			a[i]= a[i-1]+ 1.0*c[i];
			b[i]= b[i-1]+ 1.0*c[i]*c[i];
		}
		if(k== n)
		{
			printf("0\n");
			continue;
		}
		double ans= 0;
		for(int ll= 1; ll<= k+1; ll++)
		{
			int rr= ll+ n- k- 1;
			double t= (a[rr]- a[ll-1])/(n-k);
			double s= ( b[rr]- b[ll-1] )+ (n-k)*t*t - 2*t*(a[rr]- a[ll-1]);
			if(ll== 1)
				ans= s;
			else
				ans= min(ans, s);	
		}
		printf("%.10lf\n",ans);
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值