4 6 -4 -1 -1 -2 2 -4 0 2 0 3 5 -2 6 0 0 2 0 -5 -2 2 -2 -1 2 4 0 5 -5 1 -1 3 3 1 3 -1 1 -1 10 -1 -1 -3 2 -4 4 5 2 5 -4 3 -1 4 3 -1 -2 3 4 -2 2
20 15 14 38HintIn the first case, the meeting point is (0,2); the second is (0,0), the third is (1,-1) and the last is (-1,-1)
思路:
因此将x变成x+y,y->x-y;就可以算曼哈顿距离了。
x,y到某点的曼哈顿距离可以分开算,因此,分开枚举以某点为中心的值球最小就好了。
预处理,kx[x]以某点 x为中心的所有x距离和,ky[]同理。kx[i]=kx[i-1]+(i-n+i)*(f[i].x-f[i-1].x);
就是将其按照 X,Y排序,答案在中间段取点,但应该枚举几个呢???这是个问题,所以有点狗屎
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int mm=2e5+9; class node { public: __int64 x,y; int id; } f[mm]; bool cmpx(node a,node b) { return a.x<b.x; } bool cmpy(node a,node b) { return a.y<b.y; } __int64 kx[mm],ky[mm]; __int64 sum; __int64 aabs(__int64 x) { if(x<0)return -x; return x; } int main() { int cas;__int64 n,xx,yy; while(~scanf("%d",&cas)) { while(cas--) { scanf("%I64d",&n); for(int i=0; i<n; ++i) { scanf("%I64d%I64d",&xx,&yy); f[i].x=xx-yy;f[i].y=xx+yy; } sort(f,f+n,cmpx); kx[0]=0; for(int i=0; i<n; ++i) { kx[0]+=aabs(f[i].x-f[0].x); f[i].id=i; } for(__int64 i=1; i<n; ++i) kx[i]=kx[i-1]+(i-n+i)*(f[i].x-f[i-1].x); //for(int i=0;i<n;++i) //cout<<" "<<kx[i]<<" ";puts(""); sort(f,f+n,cmpy); ky[0]=0; for(int i=0;i<n;++i) ky[0]+=aabs(f[i].y-f[0].y); for(__int64 i=1;i<n;++i) ky[i]=ky[i-1]+(i+i-n)*(f[i].y-f[i-1].y); //for(int i=0;i<n ;++i) //cout<<" "<<ky[i]<<" ";puts(""); sum=6e18; for(int i=0;i<n;++i) { //cout<<f[i].id<<" "<<i<<" "<<kx[f[i].id]<<" "<<ky[i]<<" "<<ky[i]+kx[f[i].id]<<endl; if(sum>ky[i]+kx[f[i].id])sum=ky[i]+kx[f[i].id]; } printf("%I64d\n",sum/2); } } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; const int maxn = 1000010; pair<int,int> p[maxn]; int abs1(int a) { return a<0?-a:a; } int main() { int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d %d",&p[i].first,&p[i].second); sort(p,p+n); int l = max(n/2-250,0); int r = min(n/2+250,n); __int64 ans = 999999999999999LL; //cout << ans << endl; for(int i=l;i<r;i++) { __int64 tmp = 0; for(int j=0;j<n;j++) tmp += max(abs1(p[j].first-p[i].first),abs1(p[j].second-p[i].second)); ans = min(ans,tmp); } printf("%I64d\n",ans); } return 0; } /* 3 10 88 0 1 0 5 1 0 2 0 0 1 1 1 */