在一个平面上有n(1<=n<=100000)个村庄,每个村庄通过坐标(xi,yi)标示位置,-10^9<=xi,yi<=10^9。现在想要建一个邮局,使得到各个村庄的距离之和最短。
在这个问题中,距离定义为曼哈顿距离,即点i和点j的距离等于|xi-xj|+|yi-yj|
输入第一行为n,表示村庄的数量
接下来n行每行有两个整数,表示一个村庄的坐标
输出一个数字,表示建立的邮局到各个村庄的和
提示:
村庄和邮局的坐标都一定为整数
对于超过int的数字,请用long long,输入和读取用%lld
求的是曼哈顿距离,只用计算横竖距离即可。而在两个点(再加上xy坐标)构成的矩形里的任何一点时距离之和就是固定的。所以要找点的话就找被所有矩形都包括的点即可。而又不用找这样的点,只用找距离,这样就简单许多了,也就直接把这些矩形的长和宽之和相加就行了。因为只用求曼哈顿距离,所以分开,分别求x轴和y轴的距离就行。至于找矩形长/宽的长度,就是x轴上最左和最右的连起来,次左和次右的连起来……把这些长度都加起来就是x方向的了。y轴一样。由此即可得到sum值。
AC代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
long long int x[100005], y[100005];//只能横竖走,所以分开看就行
int comp(const void*a, const void*b)
{
return *(long long int*)a - *(long long int*)b;
}
int main()
{
int n;
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
scanf("%lld%lld", &x[i], &y[i]);
qsort(x, n, sizeof(long long int), comp);
qsort(y, n, sizeof(long long int), comp);
long long sum = 0;
for (i = 0; i < n; i++)
sum += abs(x[n - 1 - i] - x[i]);
for (i = 0; i < n; i++)
sum += abs(y[n - 1 - i] - y[i]);
printf("%lld\n", sum/2);//sum全都加了两遍,最后除2
return 0;
}