您的位置:首页 > 其它

NYOJ7街区最短路径问题

2017-03-30 20:23 232 查看
描述

一个街区有很多住户,街区的街道只能为东西、南北两种方向。

住户只可以沿着街道行走。

各个街道之间的间隔相等。

用(x,y)来表示住户坐在的街区。

例如(4,20),表示用户在东西方向第4个街道,南北方向第20个街道。

现在要建一个邮局,使得各个住户到邮局的距离之和最少。

求现在这个邮局应该建在那个地方使得所有住户距离之和最小;

输入

第一行一个整数n<20,表示有n组测试数据,下面是n组数据;

每组第一行一个整数m<20,表示本组有m个住户,下面的m行每行有两个整数0<x,y<100,表示某个用户所在街区的坐标。

m行后是新一组的数据;

输出

每组数据输出到邮局最小的距离和,回车结束;

样例输入

2

3

1 1

2 1

1 2

5

2 9 

5 20

11 9

1 1

1 20

样例输出

2
44

题目的关键是街区的街道只有南北和东西向的,在其中任意选择一个住户为原点建立坐标系,可以看出题目中仅可以沿着x轴和y轴的方向移动,即两点之间的距离是两点的横坐标差的绝对值和纵坐标差绝对值之和。设邮局设在某个坐标处,然后画出其它每个住户和邮局的路线,可以看出所有路线可以直接分为两个部分,即与x轴平行的路线和与y轴平行的路线,可以看出总路线长为邮局到住户的横坐标绝对值之和和纵坐标绝对值之和的和。。即原问题可以分解为分别找到令x轴和y轴方向路线最短的坐标。

此处,需要知道在一个数组中令上述路线最短的点即该数组的中位数。这句话在刘汝佳《算法竞赛入门经典训练指南》中开篇处就有详细讲解。至于读到这里的同学们只需要自己脑补一下数轴即可。可以发现邮局不在中位数时始终比在中位数时多出一段。具体证明省略。。

由上述定理即可得邮局在x轴坐标数组中位数和y轴坐标中位数的交点上。因为是中位数,所以需要先对数组进行排序。

注意原解为暴力遍历所有整数节点得到其中的最小值。同学可以先自己按上述思路写出程序,我自己有时间的时候会补上上述思路的程序。

而且看过问题的题目规模后确实是可以用暴力尝试的方法求解的。。但问题并不能保证解的x,y坐标一定是整数。

/*nyoj7 唐小晨000 2016-7-25*/

import java.util.Scanner;

public class Main{
public static void main(String[]args){
int dataNum;
int num;
int x,y;
int maxx=0,maxy=0;
int size=0;
int min=10000000;
int result=0;
pos[]data=new pos[105];
Scanner in=new Scanner(System.in);
dataNum=in.nextInt();
for(int i=0;i<dataNum;i++){
num=in.nextInt();
for(int j=0;j<num;j++){
x=in.nextInt();
if(maxx<x)
maxx=x;
y=in.nextInt();
if(maxy<y)
maxy=y;
data[size]=new pos(x,y);
size++;
}
for(int m=0;m<=maxx;m++)
for(int n=0;n<=maxy;n++){
result=0;
pos post=new pos(m,n);
for(int z=0;z<num;z++){
result+=post.dis(data[z]);
}
if(min>result)
min=result;
}
System.out.println(min);
min=10000000;
size=0;
maxx=0;
maxy=0;
}
}
}
class pos{
public int x;
public int y;
public pos(int x,int y){
this.x=x;
this.y=y;
}
public int dis(pos other){
return Math.abs(x-other.x)+Math.abs(y-other.y);
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: