您的位置:首页 > 其它

蓝桥杯真题:C村建k个邮局

2014-12-08 17:54 169 查看
标题:邮局

C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。

现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。

【输入格式】

输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。

接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。

接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。

在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。

【输出格式】

输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号)

【样例输入】

5 4 2

0 0

2 0

3 1

3 3

1 1

0 1

1 0

2 1

3 2

【样例输出】

2 4

【数据规模和约定】

对于30%的数据,1<=n<=10,1<=m<=10,1<=k<=5;

对于60%的数据,1<=m<=20;

对于100%的数据,1<=n<=50,1<=m<=25,1<=k<=10。

【资源约定】

 峰值内存消耗 < 64M
CPU消耗  < 3000ms

-------------------------------------------

思路:用死办法,遍历每种结果取最小值。

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import static java.lang.Math.*;
public class BlueBridgeExcercise5{
private static int[] combiArr; //临时数组
private static double[][] distance; //所有距离数据
private static ArrayList<int[]> combiList = new ArrayList<int[]>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //村民的户数
int m = sc.nextInt(); //备选邮局数
int k = sc.nextInt(); //要建邮局数
int[] nArrX = new int
; //村民家坐标
int[] nArrY = new int
;
int[] mArrX = new int[m]; //备选邮局坐标
int[] mArrY = new int[m];
for(int i = 0; i < n; i++){ //输入坐标
nArrX[i] = sc.nextInt();
nArrY[i] = sc.nextInt();
}
for(int i = 0; i < m; i++){
mArrX[i] = sc.nextInt();
mArrY[i] = sc.nextInt();
}
distance = new double
[m]; //村民家与备选邮局间的距离
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
distance[i][j] = sqrt(pow(nArrX[i]-mArrX[j], 2) + pow(nArrY[i]-mArrY[j], 2));
}
}
combiArr = new int[k];
combination(m-1, k, 0);
int[] best = findLeast(n);
for(int i = best.length-1; i >= 0; i--){
System.out.print((best[i]+1) + " ");//运算时编号为0~m-1,加上为题设
}
}

//找出所有组合
private static void combination(int mMax, int k, int kMax){
if(k==1){
for(int i = mMax; i >= 0; i--){
combiArr[kMax] = i;
int[] temp = Arrays.copyOf(combiArr, combiArr.length);//不能直接add原数组
combiList.add(temp);
}
}
else{
for(int i = mMax; i >= k-1; i--){
combiArr[kMax] = i;
combination(i-1, k-1, kMax+1);
}
}
}

//找出最短路径的组合
private static int[] findLeast(int n){
double sumLength = 0;
int[] best = combiList.get(0);
int[] temp;
double[] tempEvery = new double[best.length];
for(int i = 0; i < n; i++){
for(int k = 0; k < best.length; k++){
tempEvery[k] = distance[i][best[k]];
}
Arrays.sort(tempEvery);
sumLength += tempEvery[0];//加上到备选邮局的最小距离
}
double shortest = sumLength;
for(int j = 1; j < combiList.size(); j++){
temp = combiList.get(j);
sumLength = 0;
for(int i = 0; i < n; i++){
for(int k = 0; k < temp.length; k++){
tempEvery[k] = distance[i][temp[k]];
}
Arrays.sort(tempEvery);
sumLength += tempEvery[0];
}
if(sumLength < shortest){
shortest = sumLength;
best = temp;
}
}
return best;
}
}


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