【庞果网】建立信号基站题解

题目详情

要建立一个信号基站服务n个村庄,这n个村庄用平面上的n个点表示。假设基站建立的位置在(X,Y),则它对某个村庄(x,y)的距离为max{|X – x|, |Y – y|}, 其中| |表示绝对值,我们的目标是让所有村庄到信号基站的距离和最小。

基站可以建立在任何实数坐标位置上,也可以与某村庄重合。


输入

给定每个村庄的位置x[],y[],x,y都是整数,满足:

           -1000000000 < x,y < 1000000000

村庄个数大于1,小于101。

输出

所有村庄到信号基站的距离和的最小值。

关于精度:

因为输出是double。我们这样判断对错,如果标准答案是A,你的答案是a,如果|A – a| < 1e-3 我们认为是正确的,否则认为是错误的。


样例

假设有4个村庄位置分别为 (1,4) (2,3) (0,1) (1,1)

我们的结果是5。因为我们可以选择(1.5,2.5)来建立信号基站。

bestDistance = max(|1.5-1|, |2.5-4|) + max(|1.5-2|,|2.5-3|) + max(|1.5-0|,|2.5-1|) + max(|1.5-1|,|2.5-1|)

= max(0.5, 1.5) + max(0.5,0.5) + max(1.5,1.5) + max(0.5,1.5)

= 1.5 + 0.5 + 1.5 + 1.5

= 5


函数头部:

C/C++

double bestDistance(int n, cons int *x, const int *y);


题解

一开始看到这个题目,我先考虑三个村庄的情况,貌似是取三个村庄组成的三角形中的某一个平衡点。是几何图形中的某一个心吗?不得而知。然后觉得似乎是把X坐标排序后取中值,Y坐标排序后取中值,这两个值组合的位置为最佳建站位置。用数据尝试的结果,很不幸,不是这么简单的!


之后把这个问题搁浅了几天,后来在群里看到大家讨论这个题目,谈到了切比雪夫距离。于是开始google。

http://zh.wikipedia.org/wiki/%E5%88%87%E6%AF%94%E9%9B%AA%E5%A4%AB%E8%B7%9D%E7%A6%BB  维基百科对 切比雪夫距离的解释为:

两个点之间的距离定义为其各座标数值差的最大值[2]。以(x1,y1)和(x2,y2)二点为例,其切比雪夫距离为max(|x2-x1|,|y2-y1|)。

(这不就是题目里面对距离的定义嘛,所以我们要求的距离就是 切比雪夫距离之和的最小值)

在页面的最后有下面这段话,值得注意:

二维空间下,和一点的曼哈顿距离L1为定值r的点也会形成一个正方形,但其边长为√2r,而且正方形的边和坐标轴会有π/4(45°)的夹角,因此平面的切比雪夫距离可以视为平面曼哈顿距离旋转再放大后的结果。


而对于曼哈顿距离就比较简单了,这个在我前面写A星寻路算法的时候刚好了解了一下,曼哈顿距离就是X坐标之差+Y坐标之差,例如两个点A(0,0),B(1,2),AB的曼哈顿距离为3(X坐标相差1,Y坐标相差2,和为3)。


根据上面提到的,平面上的切比雪夫距离和曼哈顿距离可以互相转换。我们画出坐标图来看看是不是真的可以互相转换呢?

仍然以A(0,0),B(1,2)两个点来举例,这两个点之间的切比雪夫距离为MAX((1-0),(2-0)) = 2。

现在,我们开始做切比雪夫距离到曼哈顿距离的转换。怎么转换呢?点的位置不动,把坐标系向逆时针方向旋转45度角,这时得到的新坐标系见下图。


现在,在新的坐标系下,A的坐标还是(0,0),B的坐标变为B'(3/√2,1/√2)【3除以根号2,和1除以根号2】。我们计算一下在新坐标系下,AB两点之间的曼哈顿距离是多少?

新坐标系中AB两点之间的曼哈顿距离 = 3/√2 + 1/√2 = 4/√2 = 2*√2。

现在,我们可以把AB两点放在更一般的位置来分析,最后得到的结论是:

新坐标系中AB两点之间的曼哈顿距离 = 原坐标系下AB两点之间的切比雪夫距离 * √2。(这个结论在这里得到的比较突兀,不过多试几个例子,然后对照图形变换还是可以得证的)


坐标(x,y),将其绕坐标原点顺时针旋转角度α后的新坐标计算公式为:(xcosa-ysina,ycosa+xsina)。这里我们顺时针旋转了360-45度,所以公式为((x+y)/√2, (y-x)/√2)。

又因为根据上面的结论“新坐标系中AB两点之间的曼哈顿距离 = 原坐标系下AB两点之间的切比雪夫 * √2”,所以我们还需要再除以√2。所以最终公式为((x+y)/2, (y-x)/2)。因为除2会引入浮点数,我们可以先不除2,暂用整数来做运算。只在最后输出结果时再除以2。


将所有的点转换到新的坐标系下之后,我们现在要计算的就是曼哈顿距离和的最小值了。而曼哈顿距离包含X轴方向和Y轴方向两个互不干涉、互相正交而没有影响的两个方向的距离。我们就可以分别考虑X坐标和Y坐标了。


毫无疑问,所有村庄的X坐标组成的数组到信号基站所在位置的X坐标的距离和要最小,那么基站的X坐标应该在所有村庄的X坐标的中位数位置。信号基站的Y轴同理需要满足同样的要求。求中位数采用快排的思路可以在O(N)的时间复杂度下得到。得到X,Y坐标的中位数之后,题目要求的最短距离也就可以计算出来了。


当然,如果你和我一样偷懒,为了避免引入浮点数在之前没有除以2,那么记得在最后除以2再输出结果。 =.=


Have fun.


猜你喜欢

转载自blog.csdn.net/sun2043430/article/details/11692417