暴力吧……大概?
为了减轻暴力的负担,稍微处理一下,并不复杂
对于某两点间的曼哈顿距离,dis=abs(x1-x2)+abs(y1-y2)
这里点很多很多,很容易想到,为了简化处理,可以利用前缀和,然后我们就需要想办法处理一下绝对值的问题
如果我们对两点间的大小进行排序,就可以把绝对值去掉啦
对横纵坐标分别排序,分别求 sumx[i]=i*x[i]-pre_sumx[i-1]+pre_sumx[n]-prex_sumx[i]-(n-i)*x[i];
sumy[i]=i*y[i]-pre_sumy[i-1]+pre_sumy[n]-pre_sumy[i]-(n-i)*y[i];
然后暴力扫一遍,记录i为中心时的最小sumx[i]+sumy[i]
虽然为了处理横纵坐标前缀和的问题是分开考虑,但是最后结果的处理不是,所以用结构体保存一下横纵坐标和sumx(sumy)就可以了
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAX= 1e5+5; ll t,n,presumx[MAX],presumy[MAX]; struct pos { ll x,y,mark; }p[MAX]; bool cmpx(pos a,pos b) { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } bool cmpy(pos a,pos b) { if(a.y==b.y) return a.x<b.x; return a.y<b.y; } int main() { cin>>t; while(t--) { cin>>n; ll ans=1e18; presumx[0]=0,presumy[0]=0; for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y; sort(p+1,p+n+1,cmpx); for(int i=1;i<=n;i++) presumx[i]=presumx[i-1]+p[i].x; for(int i=1;i<=n;i++) { ll tempx=p[i].x*(i-1)-presumx[i-1]+presumx[n]-presumx[i]-p[i].x*(n-i); p[i].mark=tempx; } sort(p+1,p+1+n,cmpy); for(int i=1;i<=n;i++) presumy[i]=presumy[i-1]+p[i].y; for(int i=1;i<=n;i++) { ll tempy=p[i].y*(i-1)-presumy[i-1]+presumy[n]-presumy[i]-p[i].y*(n-i); ans=min(ans,p[i].mark+tempy); } cout<<ans<<endl; } return 0; }