http://acm.hdu.edu.cn/showproblem.php?pid=4311
http://acm.hdu.edu.cn/showproblem.php?pid=4312
4311 Finds the Sum of Manhattan Distances in Minimum Space and 4312 Finds the Sum of Chebyshev Distances in Minimum Space
Summary of Three Spatial Distances http://www.cnblogs.com/adelalove/p/8612540.html
Manhattan Distance
In Manhattan distance, x and y don't want to do with each other and sort separately, then find a prefix and suffix.
If the answer does not require a point, rank each dimension directly in the median.
#include <bits/stdc++.h> using namespace std; #define ll long long const ll N=0x3f3f3f3f3f3f3f3f; struct node { ll x,y; int id; }; node point[100010]; ll pre[100010],post[100010]; int n; bool cmpI(node n1,node n2) { return n1.x<n2.x; } bool cmpII(node n1,node n2) { return n1.y<n2.y; } ll getmin(ll a,ll b) { if(a<b) return a; else return b; } int main() { ll i,sum,ans; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { point[i].id=i; scanf("%lld%lld",&point[i].x,&point[i].y); } memset(pre,0,sizeof(pre)); memset(post,0,sizeof(post)); sort(point+1,point+n+1,cmpI); sum=0; for(i=2;i<=n;i++) { sum+=(i-1)*(point[i].x-point[i-1].x); pre[point[i].id]+=sum; } sum=0; for(i=n-1;i>=1;i--) { sum+=(n-i)*(point[i+1].x-point[i].x); post[point[i].id]+=sum; } sort(point+1,point+n+1,cmpII); sum=0; for(i=2;i<=n;i++) { sum+=(i-1)*(point[i].y-point[i-1].y); pre[point[i].id]+=sum; } sum=0; for(i=n-1;i>=1;i--) { sum+=(n-i)*(point[i+1].y-point[i].y); post[point[i].id]+=sum; } ans=N; for(i=1;i<=n;i++) ans=getmin(ans,pre[i]+post[i]); printf("%lld\n",ans); } return 0; }
Chebyshev Distance
Unexpectedly, math is too bad and there are too few problems to solve.
For two points (x1,y1) (x2,y2)
dis = max(x2-x1,y2-y1) = ( |(x2-x1)+(y2-y1)| + |(x2-x1)-(y2-y1)| ) / 2 = ( |(x2+y2)-(x1+y1)| + |(x2-y2)-(x1-y1)| ) / 2
In this way, the Chebyshev distance between (x1,y1) (x2,y2) is converted to the Manhattan distance between (x1+y1,x1-y1) (x2+y2,x2-y2).
#include <bits/stdc++.h> using namespace std; #define ll long long const ll N=0x3f3f3f3f3f3f3f3f; struct node { ll x,y; int id; }; node point[100010]; ll pre[100010],post[100010]; int n; bool cmpI(node n1,node n2) { return n1.x<n2.x; } bool cmpII(node n1,node n2) { return n1.y<n2.y; } ll getmin(ll a,ll b) { if(a<b) return a; else return b; } int main() { ll i,x,y,sum,ans; int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { point[i].id=i; scanf("%lld%lld",&x,&y); point[i].x=x+y,point[i].y=x-y; } memset(pre,0,sizeof(pre)); memset(post,0,sizeof(post)); sort(point+1,point+n+1,cmpI); sum=0; for(i=2;i<=n;i++) { sum+=(i-1)*(point[i].x-point[i-1].x); pre[point[i].id]+=sum; } sum=0; for(i=n-1;i>=1;i--) { sum+=(n-i)*(point[i+1].x-point[i].x); post[point[i].id]+=sum; } sort(point+1,point+n+1,cmpII); sum=0; for(i=2;i<=n;i++) { sum+=(i-1)*(point[i].y-point[i-1].y); pre[point[i].id]+=sum; } sum=0; for(i=n-1;i>=1;i--) { sum+=(n-i)*(point[i+1].y-point[i].y); post[point[i].id]+=sum; } ans=N; for(i=1;i<=n;i++) ans=getmin(ans,pre[i]+post[i]); printf("%lld\n",ans/2); } return 0; }