大意:给出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); }