描述
一个街区有很多住户,街区的街道只能为东西、南北两种方向。
住户只可以沿着街道行走。
各个街道之间的间隔相等。
用(x,y)来表示住户坐在的街区。
例如(4,20),表示用户在东西方向第4个街道,南北方向第20个街道。
现在要建一个邮局,使得各个住户到邮局的距离之和最少。
求现在这个邮局应该建在那个地方使得所有住户距离之和最小;
住户只可以沿着街道行走。
各个街道之间的间隔相等。
用(x,y)来表示住户坐在的街区。
例如(4,20),表示用户在东西方向第4个街道,南北方向第20个街道。
现在要建一个邮局,使得各个住户到邮局的距离之和最少。
求现在这个邮局应该建在那个地方使得所有住户距离之和最小;
-
输入
- 第一行一个整数n<20,表示有n组测试数据,下面是n组数据;
每组第一行一个整数m<20,表示本组有m个住户,下面的m行每行有两个整数0<x,y<100,表示某个用户所在街区的坐标。
m行后是新一组的数据;
输出
每组数据输出到邮局最小的距离和,回车结束;
Java代码实现:
import java.util.*;
/**
* 街区最短路径问题
* @author sdu20
*
*/
public class MinStreet {
private static int disMin(int[][] points){
if(points.length==1){
return 0;
}
int minx = points[0][0];
int miny = points[0][1];
int maxx = points[0][0];
int maxy = points[0][1];
for(int i = 1;i<points.length;i++){
if(minx>points[i][0])
minx = points[i][0];
else if(maxx<points[i][0])
maxx = points[i][0];
if(miny>points[i][1])
miny = points[i][1];
else if(maxy<points[i][1])
maxy = points[i][1];
}
int minsum = 0;
for(int k = 0;k<points.length;k++)
minsum += Math.abs(maxx-points[k][0]) + Math.abs(maxy-points[k][1]);
for(int i = minx;i < maxx;i++){
for(int j = miny;j < maxy;j++){
int sum = 0;
for(int k = 0;k<points.length;k++){
sum += Math.abs(i-points[k][0]) + Math.abs(j-points[k][1]);
}
if(minsum>sum)
minsum = sum;
}
}
return minsum;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// int[][] nums = {{2,9},{5,20},{11,9},{1,1},{1,20}};
// System.out.println(disMin(nums));
Scanner in = new Scanner(System.in);
int arraysnum = in.nextInt();
int[] results = new int[arraysnum];
for(int i = 0;i<arraysnum;i++){
int alen = in.nextInt();
int[][] points = new int[alen][2];
for(int j = 0;j<alen;j++){
points[j][0] = in.nextInt();
points[j][1] = in.nextInt();
}
results[i] = disMin(points);
}
for(int i = 0;i<arraysnum;i++){
System.out.println(results[i]);
}
}
}
运行结果截图:
把main方法和dismin方法中的循环合并的话时间应该会减少不少。但是我觉着这个问题应该有另一种方法可以解出,应该是类似于用一个式子直接计算出来的那种,但是我现在还没有想出来。
==================分割线=========================
另外一种更加简短且效率更高的方法:
import java.util.*;
/**
* 街区最短路径问题的另一种解法
* @author sdu20
*
*/
public class MinStreet2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int arraysnum = in.nextInt();
int[] results = new int[arraysnum];
for(int i = 0;i<arraysnum;i++){
int arraylength = in.nextInt();
int[] x = new int[arraylength];
int[] y = new int[arraylength];
for(int j = 0;j<arraylength;j++){
x[j] = in.nextInt();
y[j] = in.nextInt();
}
Arrays.sort(x);
Arrays.sort(y);
int sum = 0;
for(int j = 0;j<arraylength/2;j++){
sum += x[arraylength-1-j]-x[j] + y[arraylength-1-j]-y[j];
}
results[i] = sum;
}
for(int i = 0;i<arraysnum;i++)
System.out.println(results[i]);
}
}