题目描述
草原上住着一群小松鼠,每个小松鼠都有一个家。时间长了,大家觉得应该聚一聚。但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理。

每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为点(x,y)和它周围的8个点(x-1,y)(x+1,y),(x,y-1),(x,y+1).(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)距离为1。

输入格式
第一行是一个整数N,表示有多少只松鼠。接下来N行,第i行是两个整数x和y,表示松鼠i的家的坐标

输出格式
一个整数,表示松鼠为了聚会走的路程和最小是多少。

输入输出样例
输入 #1复制

6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2
输出 #1复制
20
输入 #2复制
6
0 0
2 0
-5 -2
2 -2
-1 2
4 0
输出 #2复制
15
说明/提示
样例解释
在第一个样例中,松鼠在第二只松鼠家(-1,-2)聚会;在第二个样例中,松鼠在第一只松鼠家(0.0)聚会。

数据范围
30%的数据,0 ≤ N ≤ 1000

100%的数据,0 ≤ N ≤ 100000; −10^9 ≤ x, y ≤ 10^9


空间距离变换题目,实际没什么难度。

我们由切比雪夫距离和曼哈顿距离的变换可知:

将一个点(x,y)的坐标变为(x+y,x−y)后,原坐标系中的曼哈顿距离 = 新坐标系中的切比雪夫距离
将一个点(x,y)的坐标变为(x+y2,x−y2) 后,原坐标系中的切比雪夫距离 = 新坐标系中的曼哈顿距离


然后题目给出了切比雪夫距离,我们变为曼哈顿距离,然后曼哈顿距离,x和y的计算是可以分开的,然后我们计算前缀和,就可以分别算出贡献值了。


AC代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,res=1e18,x[N],y[N],sx[N],sy[N];
struct node{int x,y;}t[N];
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%lld %lld",&x[i],&y[i]); t[i].x=x[i]+y[i]; t[i].y=x[i]-y[i];
        x[i]=t[i].x;    y[i]=t[i].y;
    }
    sort(x+1,x+1+n);    sort(y+1,y+1+n);
    for(int i=1;i<=n;i++)   sx[i]=x[i]+sx[i-1];
    for(int i=1;i<=n;i++)   sy[i]=y[i]+sy[i-1];
    for(int i=1;i<=n;i++){
        int l=lower_bound(x+1,x+1+n,t[i].x)-x;
        int r=lower_bound(y+1,y+1+n,t[i].y)-y;
        int s=l*t[i].x-sx[l]+(sx[n]-sx[l]-(n-l)*t[i].x);
        s+=r*t[i].y-sy[r]+(sy[n]-sy[r]-(n-r)*t[i].y);
        res=min(res,s);
    }
    cout<<(res>>1ll)<<endl;
    return 0;
}