您的位置:首页 > 其它

一类最短距离问题

2011-03-02 12:49 260 查看
在一个纵横间距为1的网格地图上,有n个比赛选手,他们分别位于某个纵横交点(即x和y坐标都是1的整倍数),将参加一个循环赛(即任意两个选手之间都需要进行比赛),你是赛事的组织者,要结合选手的位置信息来设计一个最佳的比赛赛程,使得他们走的路程总和最少(注选手只能沿着网格线走,不能沿任何对角线穿越),选手一旦完成所有比赛后,可以任意选择行动或停在原地,不需要回到其原来位置。

比如:如果有选手A(0,0),B(0,2),C(2,0),D(1,1),E(2,2),则一个可能的最佳解为:A和B走到(0,1)比赛,C和E走到(2,1)比赛,然后ABCE都走到D处(1,1)比赛,进行剩余所有比赛,所有选手共走了8个单位的距离。

其实,题目示例本身带有一定的迷惑性,分析可知,如果让所有的比赛都在D处(1,1)进行,也能够得到同解,因为是循环赛,任意两个选手都需要碰面,早碰晚碰并没有关系,但是这个分析可以简化解题思路,即我们只需要找出这么一个点,使得所有选手到它的水平和垂直距离差之和最小。

第一想到的可能是重心点,即x=sum{x1,...,xn}/n, y=sum{y1,...yn}/n,改点坐标可能带小数,再测试该点周围的网格点取最小值,这个思路似乎也贴合示例题解,但是,取个任意的x坐标数组,假设为{1,2,3,9,10,100},重心x=20.83,它在10和100之间,但是换一个角度,如果将取值点前移一个小的delta,在它之前的m个点都缩进delta,在它之后的l各点则延伸delta,总共可以降低(l-m)*delta,扩展一点,如果左侧的点比右侧多,则继续向左移近对降低总距离有益,反正亦然(x坐标和y坐标都适用),所以重心点未必是最佳位置,合理的位置应该是有序坐标的中间点位置,如果数组个数为奇数,则取中间点;如果为偶数,则中间两个点任取一个都可以。

所以,比赛场次安排和比赛地点都是幌子,最后的解显得很简洁。

public int getTravelDistance(int[] X, int[] Y)
{
Arrays.sort(X);
Arrays.sort(Y);
int dist = 0;
for(int i=0; i<X.length; i++)
dist += Math.abs(X[i]-X[X.length/2]);
for(int i=0; i<Y.length; i++)
dist += Math.abs(Y[i]-Y[Y.length/2]);
return dist;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: