题意:在一个无限平面直角坐标系中,有n个点,求其中的一个点,各个点到他的距离最小。
利用扫描的思想,分别从x轴负方向和x轴正方向扫描,求各个点到他的最小距离。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
long long fa[500100],fb[500100],fc[500100],fd[500100];
long long ans;
struct sa
{
long long x,y;
int id;
};
sa N[500100];//这个地方不能写在main函数里面,就因为这个,我找了将近一天啊!!!!
int cmp1(sa a,sa b)
{
return a.x<b.x;
}
int cmp2(sa a,sa b)
{
return a.y<b.y;
}
int main()
{
int t,n,i,cnt;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(fa,0,sizeof(fa));
memset(fb,0,sizeof(fb));
memset(fc,0,sizeof(fc));
memset(fd,0,sizeof(fd));
for(i=0;i<n;i++)
{
scanf("%I64d%I64d",&N[i].x,&N[i].y);
N[i].id=i;
}
sort(N,N+n,cmp1);
fa[0]=0;
cnt=1;
for(i=1;i<n;i++)
fa[N[i].id]=(fa[N[i-1].id]+(N[i].x-N[i-1].x)*cnt),cnt++;
fb[n-1]=0;
cnt=1;
for(i=n-2;i>=0;i--)
fb[N[i].id]=(fb[N[i+1].id]+(N[i+1].x-N[i].x)*cnt),cnt++;
sort(N,N+n,cmp2);
fc[0]=0;
cnt=1;
for(i=1;i<n;i++)
fc[N[i].id]=(fc[N[i-1].id]+(N[i].y-N[i-1].y)*cnt),cnt++;
fd[n-1]=0;
cnt=1;
for(i=n-2;i>=0;i--)
fd[N[i].id]=(fd[N[i+1].id]+(N[i+1].y-N[i].y)*cnt),cnt++;
ans=9999999999999999LL;
for(i=0;i<n;i++)
ans=min(ans,fa[i]+fb[i]+fc[i]+fd[i]);
printf("%I64d\n",ans);
}
return 0;
}