HDU 4311 曼哈顿距离

HDU 4311 Meeting point-1 曼哈顿距离

题意:给出n个点的xy坐标,选其中一个点,使得其他点到他的曼哈顿距离最小,求最小的曼哈顿距离

题解:先按x坐标从小到大排序,求出其他点到第一个点的距离和,根据递推把所有的点都求出来,复杂度O(N),y坐标也是,最后记录最小和。

#include <cstdio>
#include <algorithm>
#include <cmath>
using std::sort;
struct node
{
    long long sumx, sumy, x, y;
}G[100010];
bool cmp1(node a, node b) {
    return a.x < b.x;
}
bool cmp2(node a, node b) {
    return a.y < b.y;
}
int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%lld %lld", &G[i].x, &G[i].y);
        }
        sort(G, G + n, cmp1);
        long long summ = 0;
        for(int i = 1; i < n; i++) {
            summ += (G[i].x - G[0].x);
        }
        G[0].sumx = summ;
        for(int i = 1; i < n; i++) {
            G[i].sumx = G[i-1].sumx + (G[i].x - G[i-1].x) * (2 * i - n);
        }
        sort(G, G + n, cmp2);
        summ = 0;
        for(int i = 1; i < n; i++) {
            summ += (G[i].y - G[0].y);
        }
        G[0].sumy = summ;
        long long ans = G[0].sumx + G[0].sumy;
        for(int i = 1; i < n; i++) {
            G[i].sumy = G[i-1].sumy + (G[i].y - G[i-1].y) * (2 * i - n);
            if(ans > G[i].sumx + G[i].sumy) ans = G[i].sumx + G[i].sumy;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fanshhh/p/11874686.html