Description
有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。
Input
第一行给出数字N,表示有多少只小松鼠。0<=N<=10^5
下面N行,每行给出x,y表示其家的坐标。
-10^9<=x,y<=10^9
Output
表示为了聚会走的路程和最小为多少。
Sample Input
6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2
Sample Output
20
题解
http://blog.csdn.net/slongle_amazing/article/details/50911504
转换成曼哈顿距离
(x,y)->((x+y)/2,(x-y)/2)
代码
#include<bits/stdc++.h>
#define mod 1000000007
#define inf 1000000000
#define N 200005
typedef long long ll;
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n;
struct point{ll x,y;int id;}a[N];
double ans=1e20;
ll sx,sy,lx[N],rx[N],ly[N],ry[N];
bool X(point a,point b){return a.x<b.x;}
bool Y(point a,point b){return a.y<b.y;}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
int X=read(),Y=read();
a[i].x=X+Y;a[i].y=X-Y;
}
sort(a+1,a+n+1,X);
for (int i=1;i<=n;i++)
{
lx[i]=lx[i-1]+a[i].x;
rx[n-i+1]=rx[n-i+2]+a[n-i+1].x;
a[i].id=i;
}
sort(a+1,a+n+1,Y);
for (int i=1;i<=n;i++)
{
ly[i]=ly[i-1]+a[i].y;
ry[n-i+1]=ry[n-i+2]+a[n-i+1].y;
}
for (int i=1;i<=n;i++)
{
ll Dis=a[i].y*(i-1)-ly[i-1]+ry[i+1]-a[i].y*(n-i);
int j=a[i].id;
Dis+=(lx[j]-lx[j-1])*(j-1)-lx[j-1]+rx[j+1]-(rx[j]-rx[j+1])*(n-j);
if (Dis<ans) ans=Dis;
}
printf("%.0lf",ans/2);
}