hdu 4311
直接暴力的话,O(n2),肯定会超时。分解到两个轴上,通过递推求解,O(nlgn)。要理解这种高效求距离的方法。数轴上的某一点到其他点的距离,可通过从小到大或从大到小递推来做。
#include <iostream>
#include <cstdio>
#include <algorithm>
#define ll _int64
using namespace std;
const int maxn=100010;
int x[maxn],y[maxn],rx[maxn],ry[maxn];
ll disx[maxn],disy[maxn];
int n;
ll solve1(int t)
{
int low=0,high=n,mid;
while(high-low>0)
{
mid=low+(high-low)/2;
if(x[mid]==t) break;
if(x[mid]<t) low=mid+1;
else high=mid;
}
return disx[mid];
}
ll solve2(int t)
{
int low=0,high=n,mid;
while(high-low>0)
{
mid=low+(high-low)/2;
if(y[mid]==t) break;
if(y[mid]<t) low=mid+1;
else high=mid;
}
return disy[mid];
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
{
scanf("%d%d",&rx[i],&ry[i]);
x[i]=rx[i];y[i]=ry[i];
}
sort(x,x+n);//排序使后续递推可以进行
sort(y,y+n);
disx[0]=disy[0]=0;
for(i=1;i<n;i++)
{
disx[0]+=x[i]-x[0];
disy[0]+=y[i]-y[0];
}
for(i=1;i<n;i++)
{
disx[i]=disx[i-1]+(ll)(x[i]-x[i-1])*i-(ll)(x[i]-x[i-1])*(n-i);
disy[i]=disy[i-1]+(ll)(y[i]-y[i-1])*i-(ll)(y[i]-y[i-1])*(n-i);
}
ll min=0x3f3f3f3f3f3f3f3f;
for(i=0;i<n;i++)
{
ll tem=solve1(rx[i])+solve2(ry[i]);
if(min>tem) min=tem;
}
printf("%I64d\n",min);
}
return 0;
}

浙公网安备 33010602011771号