hdu - 4312 - Meeting point-2 - 数学 + 想法

来源:互联网 发布:企业社交网络 编辑:程序博客网 时间:2024/05/01 09:29

题意, 一个方格到相邻八个点的距离都为1.

http://acm.hdu.edu.cn/showproblem.php?pid=4312

给你好多个点的坐标,让你求一个点满足到其他点的距离最短。

解:

   其实也是暴力枚举,貌似没有比他更好的方法。 但是枚举的时候做些预处理就行,参见4311.

   其他就需要了解的就是chebyshev距离和manhattan距离的转化了。

   我照着题解静下心来认真看了,终于觉得题解是对的了。


平面上两点间的 Chebyshev距离为 max(|x1-x2|, |y1-y2|)

                      

           Chebyshev                                                Manhattan

对于原坐标系中两点间的 Chebyshev 距离,是将坐标轴顺时针旋转45度并将所有点的坐标值放大sqrt(2)倍所得到的新坐标系中的Manhattan距离的二分之一。

大家可以画图想一下……

假设有两点(x1,y1), (x2,y2),不妨设 x1>x2(否则交换这两点即可)。

则Chebyshev距离 D1 = max(|x1-x2|, |y1-y2|)

这两点个对应到新坐标系中的坐标为 (x1-y1, x1+y1), (x2-y2, x2+y2)

则Manhattan 距离D2 = |x1-y1-x2+y2| + |x1+y1-x2-y2|



分四种情况讨论:

1.1 y1>y2 && x1-x2>y1-y2

D1 = max(x1-x2, y1-y2) = x1 - x2

D2 = x1-y1-x2+y2 + x1+y1-x2-y2 = 2(x1-x2)

1.2 y1>y2 && x1-x2<=y1-y2

D1 = max(x1-x2,y1-y2) = y1-y2

D2 = -(x1-y1-x2+y2) + x1+y1-x2-y2 = 2(y1-y2)

2.1 y1<=y2 && x1-x2>y2-y1

D1 = max(x1-x2, y2-y1) = x1-x2

D2 = x1-y1-x2+y2 + x1+y1-x2-y2 = 2(x1-x2)

2.2 y1<=y2 && x1-x2<=y2-y1

D1 = max(x1-x2, y2-y1) = y2-y1

D2 = x1-y1-x2+y2 - (x1+y1-x2-y2) = 2(y2-y1)



所以先将Chebyshev距离形式转化成Manhattan距离的形式再求解,求解过程参考 Meeting point-2


将4311代码改了三行,就过了。。。

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#define maxn 100010typedef long long L;using namespace std;struct Node{    long long x,y;    int id;} p[maxn];long long sumx[maxn],sumy[maxn];bool cmpx(Node a , Node b){    return a.x < b.x;}bool cmpy(Node a, Node b){    return a.y < b.y;}int T, n;long long tmpx, tmpy;//改的地方int main(){    scanf("%d",&T);    while(T --){        scanf("%d",&n);        for(int i = 1; i <= n; ++ i){            scanf("%I64d%I64d", &tmpx, &tmpy);            p[i].x = tmpx - tmpy;//改的地方            p[i].y = tmpx + tmpy;//改的地方        }        sort(p + 1, p + 1 + n, cmpx);        sumx[1] = p[1].x;p[1].id = 1;        for(int i = 2; i <= n; ++ i){            sumx[i] = sumx[i - 1] + p[i].x;            p[i].id = i;        }        sort(p + 1, p + 1 + n, cmpy);        sumy[1] = p[1].y;        for(int i = 2; i <= n; ++ i){            sumy[i] = sumy[i - 1] + p[i].y;        }        long long ans = (1LL << 60);//        for(int i = 1; i <= n; i ++){            int j = p[i].id;            long long yy = ( p[i].y ) * (i * 1.0) - sumy[i];            yy += (sumy[n] - sumy[i] - (p[i].y) * ((n - i) * 1.0) );            long long xx = ( p[i].x ) * (j * 1.0) - sumx[j];            xx += (sumx[n] - sumx[j] - (p[i].x) * ((n - j) * 1.0) );            xx += yy;            ans = min(xx,ans);        }        printf("%I64d\n", ans / 2);    }    return 0;}