hdu 4311

来源:互联网 发布:gre词汇精选淘宝 编辑:程序博客网 时间:2024/06/03 14:23
题意:
给你n个点。选择一个点,是其他点到这个点的Manhattan 距离最小

思路:
平面上两点间的 Manhattan 距离为 |x1-x2| + |y1-y2|

所以X 方向的距离与 Y 方向上的距离可以分开来处理。假设我们以 (xi,yi) 作为开会的地点,那么其余的点到该开会地点所需的时间为 X 方向上到 xi 所需要的时间加上 Y 方向上到 yi 所需要的时间。所以可以分别对x方向,y方向各点作文开会地点时,其他点到这个点的距离。

单独处理一维的时候,相当于求其他点到当前点的距离之和,如果点事已序的,可以O(n)求出。
所以我们对当前方向可以先排序,然后求其他点到某一个点的距离时,可以得到一个递推公式,f[i] = f[i-1] + (2 * i – n) * (x[i] – x[i - 1]);依次处理 X 方向 Y 方向就可以求出此题的解了。

代码:

#include<cstdio>#include<cmath>#include<algorithm>#include<iostream>#include<cstring> using namespace std; const int N = 100002; struct node{         long long a;         int id;         bool operator < (const node &a) const      {              return id < a.id;         }}; node x[N], y[N];node X[N], Y[N];bool cmp(node a, node b){         return a.a < b.a;} void ready(int n){         sort(x, x + n, cmp);         sort(y, y + n, cmp);         memset(X, 0, sizeof(X));         memset(Y, 0, sizeof(Y));          for(int i = 1; i < n; i ++)     {                X[0].a += x[i].a - x[0].a;                Y[0].a += y[i].a - y[0].a;         }         X[0].id = x[0].id; Y[0].id = y[0].id;          for(int i = 1; i < n; i ++)     {                X[i].a = X[i - 1].a + (2 * i - n) * (x[i].a - x[i - 1].a);                Y[i].a = Y[i - 1].a + (2 * i - n) * (y[i].a - y[i - 1].a);                X[i].id = x[i].id;  Y[i].id = y[i].id;         }}long long  solve(int n){         sort(X, X + n);         sort(Y, Y + n);         long long minn = X[0].a + Y[0].a;         for( int i = 1; i < n; i ++)     {                      if(X[i].a + Y[i].a < minn)                          minn = X[i].a + Y[i].a;         }         return minn;} int main(){         int T, n;         scanf("%d", &T);         while(T--)     {               scanf("%d",&n);               for(int i = 0; i < n; i ++)       {                       scanf("%I64d%I64d", &x[i].a, &y[i].a);                       x[i].id = y[i].id = i;               }               ready(n);               printf("%I64d\n", solve(n));           }}