直接暴力的话,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; }