蓝桥杯历届试题(2014) PREV-24 邮局

问题描述

  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。

资源限制

时间限制:1.0s   内存限制:256.0MB

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 int n,m,k;
 5 int vis[55],tempvis[55];
 6 double dis[55][55];
 7 double sum=1e9;
 8 void dfs(int node,int cnt,double tempsum,double tempdis[55]){
 9     //剩余需要选择的邮局个数超过剩余能选择邮局数,放弃 
10     if((k-cnt)>(m-node)) return;
11     //放弃当前邮局,找下一个 
12     if((node+1)<m) dfs(node+1,cnt,tempsum,tempdis);
13     double newdis[55];
14     //复制当前tempdis状态 
15     for(int i=0;i<n;i++)
16          newdis[i] = tempdis[i];
17     //找齐k个邮局,更新最小值tempsum,复制输出最小值时
18     //的临时邮局选择数组tempvis到邮局选择数组vis 
19     if(cnt+1==k){
20         tempvis[cnt]=node;
21         for(int i=0;i<n;i++){
22             if(newdis[i]>dis[node][i]){
23                 tempsum=tempsum-newdis[i]+dis[node][i];
24                 newdis[i]=dis[node][i];
25             }
26         }
27         if(tempsum<sum){//更新sum最小值 
28             sum=tempsum;   
29             for(int i=0;i<k;i++){
30                vis[i]=tempvis[i];
31             }
32         }    
33         return ;
34     }
35     //选择当前为node的邮局 
36     tempvis[cnt]=node;
37     bool not_first=true;//初始化为非挑选的第一个邮局 
38     bool useless=true;//初始化为无用邮局 
39     if(cnt==0){//cnt==0,必为挑选的第一个邮局 
40         for(int i=0;i<n;i++){
41             tempsum=tempsum+dis[node][i];
42             newdis[i]=dis[node][i];
43         }
44         not_first=false;//修正为挑选的第一个邮局 
45     }else{//非挑选的第一个邮局 
46         for(int i=0;i<n;i++){
47             if(newdis[i]>dis[node][i]){
48                 tempsum=tempsum-newdis[i]+dis[node][i];
49                 newdis[i]=dis[node][i];
50                 useless=false;//修正为有用邮局 
51             }
52         }
53     }
54     //有用邮局或者第一个挑选的邮局都可以进入 
55     if(!(not_first&&useless)){
56         if(node+1<m){//未超过m,选择该邮局,继续挑选下一个邮局 
57             dfs(node+1,cnt+1,tempsum,newdis);
58         }
59     }
60 }
61 struct Point{
62     int x;
63     int y;
64 };
65 int main(){
66     cin>>n>>m>>k;
67     double tempdis[55];
68     Point v[55];
69     Point p[55]; 
70     for(int i=0;i<n;i++){
71         cin>>v[i].x>>v[i].y;
72     }
73     for(int i=0;i<m;i++){
74         cin>>p[i].x>>p[i].y;
75     }
76     //计算vi与pj之间的距离disji 
77     for(int i=0;i<n;i++){
78         for(int j=0;j<m;j++){
79             dis[j][i]=sqrt((v[i].x-p[j].x)*(v[i].x-p[j].x)+(v[i].y-p[j].y)*(v[i].y-p[j].y));
80         }
81     }
82     
83     dfs(0,0,0,tempdis);
84     
85     for(int i=0;i<k;i++){
86         cout<<vis[i]+1<<" ";
87     }
88     cout<<endl;
89     return 0;
90     
91 }

猜你喜欢

转载自www.cnblogs.com/memocean/p/12729342.html
今日推荐