题意:给出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
", ans);
}
return 0;
}