【校内互测】YL杯超级篮球赛

大意:给出N(N<=50000)的坐标,以及每一个点的权值w,要求求出一个点(x,y),使所有点到它的距离与各自权值之积的和最小。计算公式为w×[ABS(x-x1)+ABS(y-y1)]。

【题解】

带权中位数模板题。有关带权中位数问题见本博客学习笔记。

【代码】

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
long long n,m,sum,ansx,ansy,ans;
struct hp{
	long long tir,x,y;
}a[50005];
inline int cmp1(hp a,hp b){
	return a.x<b.x;
}
inline int cmp2(hp a,hp b){
	return a.y<b.y;
}
int main(){
	freopen("ball.in","r",stdin);
	freopen("ball.out","w",stdout);
	scanf("%I64d",&n);
	for (int i=1;i<=n;++i)
	  scanf("%d",&a[i].tir),sum+=a[i].tir;
	for (int i=1;i<=n;++i)
	  scanf("%I64d%I64d",&a[i].x,&a[i].y);
	sort(a+1,a+n+1,cmp1);
	m=0;
	for (int i=1;i<=n;++i){
		m+=a[i].tir;
		if (m>sum/2){
			ansx=a[i].x;
			break;
		}
	}
	sort(a+1,a+n+1,cmp2);
	m=0;
	for (int i=1;i<=n;++i){
		m+=a[i].tir;
		if (m>sum/2){
			ansy=a[i].y;
			break;
		}
	}
	for (int i=1;i<=n;++i)
	  ans+=(abs(a[i].x-ansx)+abs(a[i].y-ansy))*a[i].tir;
	printf("%I64d.00\n",ans);
}


你可能感兴趣的:(数论)