蓝桥杯 邮局
2018-03-29 20:29
92 查看
历届试题 邮局 时间限制:1.0s 内存限制:256.0MB 锦囊1锦囊2锦囊3问题描述 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。
题目如上:一开始看到这题目,感觉挺复杂的。但静下心来理一理 ,其实也就是深搜,再一个一个比较,只是比较麻烦了点。大概思路是,开一个数组存储村民的坐标,一个数组存储邮局的坐标,再开一个整数数组存储你选择的邮局的标号。深搜选择k个邮局,计算出每个村民到距离他最近的邮局的距离之和,再和之前得到的对比,深搜完所有k个邮局的组合后,我们就可以得到能够使得村民们到最近邮局的距离之和最小的邮局组合。
代码如下:import java.util.Scanner;public class Main {class Point1{
int x,y;
public Point1(int n,int m) {
// TODO Auto-generated constructor stub
x=n;
y=m;
}
}
static Point1[] people;
static Point1[] post;
static Point1[] temp;
static int[] vis;
static int[] posttemp;
static int m;
static int k;
static int n;
static double minresult=10000;
static int[] postreslt;
public static void main(String[] args) {
Main test=new Main();
Scanner cin=new Scanner(System.in);
n=cin.nextInt();
m=cin.nextInt();
vis=new int[m];
k=cin.nextInt();
postreslt=new int[k];
people=new Point1
;
post=new Point1[m];
posttemp=new int[k];
temp=new Point1[k];
for(int i=0;i<n;i++) {
people[i]=test.new Point1(cin.nextInt(), cin.nextInt());
}
for(int i=0;i<m;i++) {
post[i]=test.new Point1(cin.nextInt(), cin.nextInt());
}
dfs(0);
for(int i=0;i<k;i++) {
System.out.print((postreslt[i]+1)+" ");
}
//System.out.println(minresult);
}
private static void dfs(int no) {
if (no==k) {
double min;
int sum=0;
for(int j=0;j<n;j++) {
min=1000;
for(int l=0;l<k;l++) {
if (getdistance(people[j], post[posttemp[l]])<min) {
min=getdistance(people[j], post[posttemp[l]]);
}
}
sum+=min;
}
if(sum<minresult) {
minresult=sum;
for(int i=0;i<k;i++) {
postreslt[i]=posttemp[i];
}
}
return;
}
// TODO Auto-generated method stub
for(int i=0;i<m;i++) {
if (vis[i]==0) {
posttemp[no]=i;
vis[i]=1;
dfs(no+1);
vis[i]=0;
}
}
}
public static double getdistance(Point1 p1,Point1 p2) {
return Math.sqrt(Math.abs(p1.x-p2.x)*Math.abs(p1.x-p2.x)+Math.abs(p1.y-p2.y)*Math.abs(p1.y-p2.y));
}
}
接触acm已经大半年了,有时会感觉学得很累。相对与其他应用开发来说,acm可能是成本高,收益不明显的,但是,这练得都是内功,效果不会一下子出来,但是日积月累,思维方式一定会得到很好的锻炼。而且acm的很多题目都可以很好地应用于生活中。所以,加油吧~后天要参加蓝桥杯比赛了,立个flag,祝自己一切如愿,生活如此美好~~~
现在给出了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。
题目如上:一开始看到这题目,感觉挺复杂的。但静下心来理一理 ,其实也就是深搜,再一个一个比较,只是比较麻烦了点。大概思路是,开一个数组存储村民的坐标,一个数组存储邮局的坐标,再开一个整数数组存储你选择的邮局的标号。深搜选择k个邮局,计算出每个村民到距离他最近的邮局的距离之和,再和之前得到的对比,深搜完所有k个邮局的组合后,我们就可以得到能够使得村民们到最近邮局的距离之和最小的邮局组合。
代码如下:import java.util.Scanner;public class Main {class Point1{
int x,y;
public Point1(int n,int m) {
// TODO Auto-generated constructor stub
x=n;
y=m;
}
}
static Point1[] people;
static Point1[] post;
static Point1[] temp;
static int[] vis;
static int[] posttemp;
static int m;
static int k;
static int n;
static double minresult=10000;
static int[] postreslt;
public static void main(String[] args) {
Main test=new Main();
Scanner cin=new Scanner(System.in);
n=cin.nextInt();
m=cin.nextInt();
vis=new int[m];
k=cin.nextInt();
postreslt=new int[k];
people=new Point1
;
post=new Point1[m];
posttemp=new int[k];
temp=new Point1[k];
for(int i=0;i<n;i++) {
people[i]=test.new Point1(cin.nextInt(), cin.nextInt());
}
for(int i=0;i<m;i++) {
post[i]=test.new Point1(cin.nextInt(), cin.nextInt());
}
dfs(0);
for(int i=0;i<k;i++) {
System.out.print((postreslt[i]+1)+" ");
}
//System.out.println(minresult);
}
private static void dfs(int no) {
if (no==k) {
double min;
int sum=0;
for(int j=0;j<n;j++) {
min=1000;
for(int l=0;l<k;l++) {
if (getdistance(people[j], post[posttemp[l]])<min) {
min=getdistance(people[j], post[posttemp[l]]);
}
}
sum+=min;
}
if(sum<minresult) {
minresult=sum;
for(int i=0;i<k;i++) {
postreslt[i]=posttemp[i];
}
}
return;
}
// TODO Auto-generated method stub
for(int i=0;i<m;i++) {
if (vis[i]==0) {
posttemp[no]=i;
vis[i]=1;
dfs(no+1);
vis[i]=0;
}
}
}
public static double getdistance(Point1 p1,Point1 p2) {
return Math.sqrt(Math.abs(p1.x-p2.x)*Math.abs(p1.x-p2.x)+Math.abs(p1.y-p2.y)*Math.abs(p1.y-p2.y));
}
}
接触acm已经大半年了,有时会感觉学得很累。相对与其他应用开发来说,acm可能是成本高,收益不明显的,但是,这练得都是内功,效果不会一下子出来,但是日积月累,思维方式一定会得到很好的锻炼。而且acm的很多题目都可以很好地应用于生活中。所以,加油吧~后天要参加蓝桥杯比赛了,立个flag,祝自己一切如愿,生活如此美好~~~
相关文章推荐
- 蓝桥杯真题:C村建k个邮局
- 蓝桥杯--- 历届试题 邮局 (深搜+暴力)(动态待解决)
- 蓝桥杯历届试题 邮局(DFS)
- 蓝桥杯真题:C村建k个邮局
- 蓝桥杯 历届试题 邮局 (dfs得了40分,其他数据超时,代码贴出来以后改正)
- 蓝桥杯 邮局
- 蓝桥杯 历届试题 邮局 2017-09-24 修改
- 蓝桥杯 逻辑推断类型题目
- 蓝桥杯BASIC_28(huffuman树)
- 蓝桥杯 历届试题 分糖果
- 2013蓝桥杯 【初赛试题】 第39级台阶
- 第五届“蓝桥杯”全国软件和 校内选拔赛试题(Java组)4、计算蔬菜总价
- ACM准备之路(蓝桥杯7)最大最小求和
- 2012 蓝桥杯【初赛试题】微生物增殖
- 蓝桥杯(java)入门训练 序列求和
- 【第七届蓝桥杯】寒假作业
- 蓝桥杯:买不到的数目
- 蓝桥杯题目7奇怪的分式
- 【第四届蓝桥杯】马虎的算式
- 蓝桥杯--求3个数的最小公倍数