hdu 4311 Meeting point-1

来源:互联网 发布:变色龙软件下载 编辑:程序博客网 时间:2024/04/19 19:12
#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 __int64const 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;}

原创粉丝点击