#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
题意:给你n个点问在其中任选一点到其他点的距离和最小是多少。
分析:|p1p2| = |x1 – x2| + |y1 – y2|;
看数据范围是不能暴力的。我们分开求,先求x方向的的最距离,然后在加上y方向上距离。
先把点按x排序,设排序后为X0,X1,X2,…,Xn-1。然后求每个点到x0的距离和sumx;
关键点在下面:我们在求每个点到x1的距离时,sumx加上X1左边的(1-1)个|X1X0|,减去X2右边的(n-1 – 1 -1)个|X1X0|,求得新的sumx。也就说在求每个点到xi的距离时,sumx加上Xi左边的(i-1)个|XiXi-1|,减去X2右边的(n-1 – i -1)个|X1X0|,求得新的sumx。
同理可得y,加到对应的点上即可。
*/
#include <iostream>
#include <algorithm>
using namespace std;
#define ll __int64
const int maxn = 100005;
struct node
{
ll x, y,id;
}point[maxn];
ll sumy[maxn], sumx[maxn];
bool cmpx(node a, node b)
{
if(a.x != b.x)
return a.x < b.x;
return a.y < b.y;
}
bool cmpy(node a, node b)
{
if(a.y != b.y)
return a.y < b.y;
return a.x < b.x;
}
int main()
{
int t, n;
ll ans;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%I64d %I64d", &point[i].x, &point[i].y);
}
sort(point, point + n, cmpy);
sumy[0] = 0;
point[0].id= 0;
for(int i = 1; i < n; i++)
{
point[i].y -= point[0].y;
sumy[i] = sumy[i-1] + point[i].y;
point[i].id= i;
}
point[0].y = 0;
sort(point, point + n, cmpx);
sumx[0] = 0;
for(int i = 1; i < n; i++)
{
point[i].x -= point[0].x;
sumx[i] = sumx[i-1] + point[i].x;
}
point[0].x = 0;
ans = sumy[n-1] + sumx[n-1];
for(int i = 1; i < n; i++)
{
ll sum = i * point[i].x - sumx[i-1]+ sumx[n-1] - sumx[i] - (n - i - 1) * point[i].x;
sum += ( point[i].id*point[i].y - sumy[point[i].id-1] + sumy[n-1] - sumy[point[i].id] - (n -1 - point[i].id)* point[i].y );
if(sum < ans) ans = sum;
}
printf("%I64d\n", ans);
}
return 0;
}
hdu 4311 Meeting point-1
最新推荐文章于 2019-09-25 19:34:18 发布