蓝桥杯真题: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
-------------------------------------------
思路:用死办法,遍历每种结果取最小值。
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; } }
相关文章推荐
- 蓝桥杯真题:C村建k个邮局
- 第四届蓝桥杯真题总结
- 2015年第六届蓝桥杯大赛个人赛决赛(软件类)真题 标题:方格填数
- 蓝桥杯第七届省赛JAVA真题----剪邮票
- 2013年第四届蓝桥杯C/C++ C组决赛真题题解
- 第五届蓝桥杯Java B组真题——猜字母
- 2013年蓝桥杯全国软件大赛预赛真题-c语言本科
- 2013第四届蓝桥杯 C/C++本科A组 真题答案解析
- 备战蓝桥杯(真题)第七届第九题“ 四平方和”
- 算法笔记_208:第六届蓝桥杯软件类决赛真题(Java语言A组)
- 第七届蓝桥杯决赛真题 - 一步之遥
- 2017河南省B组蓝桥杯真题(1) 等差素数列
- 2017河南省B组蓝桥杯真题(1) 分巧克力
- 第四届蓝桥杯JAVA B组省赛真题-振兴中华
- 蓝桥杯2014年以前JAVA历年真题及答案整理——Excel地址转换
- 蓝桥杯2014年以前JAVA历年真题及答案整理——回文数
- 第五届蓝桥杯软件类省赛真题-C-A-1_猜年龄
- 2018省赛第九届蓝桥杯真题C语言B组详解第一题
- [置顶] 2012第三届--2017第八届 蓝桥杯省赛-C/C++真题汇总
- 蓝桥杯真题 Java B组 立方变自身