2015编程之美(资格赛)--基站选址

时间:2022-05-06
本文章向大家介绍2015编程之美(资格赛)--基站选址,主要内容包括题目3 : 基站选址、描述、输入、输出、数据范围、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

题目3 : 基站选址

时间限制:2000ms

单点时限:1000ms

内存限制:256MB

描述

需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上。

网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方。

网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离)。

在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价。

输入

第一行为一个整数T,表示数据组数。

每组数据第一行为四个整数:N, M, A, B。

接下来的A+B行每行两个整数x, y,代表一个坐标,前A行表示各用户的坐标,后B行表示各通讯公司的坐标。

输出

对于每组数据输出一行"Case #X: Y",X代表数据编号(从1开始),Y代表所求最小代价。

数据范围

1 ≤ T ≤ 20

1 ≤ x ≤ N

1 ≤ y ≤ M

1 ≤ B ≤ 100

小数据

1 ≤ N, M ≤ 100

1 ≤ A ≤ 100

大数据

1 ≤ N, M ≤ 107

1 ≤ A ≤ 1000

样例输入

2
3 3 4 1
1 2
2 1
2 3
3 2
2 2
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3

样例输出

Case #1: 4
Case #2: 13

    这道题,很不好理解:  刚开始代码思路错了n边.....
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3  
可以排除基站的坐标为(2,,3) 所以得到的数据欧几里得的距离为{x1*x1+y1*y1);
对于路程为: 直接坐标之差的绝对值(x+y);
代码:
 1 #define _CRT_SECURE_NO_WARNINGS
 2 
 3 #include<iostream>
 4 #include<string>
 5 #include<vector>
 6 #include<algorithm>
 7 #include<math.h>
 8 #include<stdio.h>
 9 #include<string.h>
10 #include<stdlib.h>
11 using namespace std;
12 const int inf = 0x3f3f3f3f;
13 struct point {
14     int x, y;
15 
16 };
17 
18 void input(point &max_p, point & min_p, vector<point> & aa, const int num) {
19 
20     point tem = { 0,0 };
21     for (int i = 0; i < num; i++) {
22         scanf("%d %d", &tem.x, &tem.y);
23         max_p.x = max(max_p.x, tem.x);
24         min_p.x = min(min_p.x, tem.x);
25         max_p.y = max(max_p.y, tem.y);
26         min_p.y = min(min_p.y, tem.y);
27         aa.push_back(tem);
28     }
29 }
30 
31 //求距离的平方
32 int dist(const point &aa, const point &bb) {
33 
34     int x = aa.x - bb.x;
35     int y = aa.y - bb.y;
36     return x*x + y*y;
37 }
38 
39 //求距离
40 int  dist_sqrt(const point &aa, const point &bb) {
41 
42     int x = abs(aa.x - bb.x);
43     int y = abs(aa.y - bb.y);
44     return  x+y;
45 }
46 
47 int work(const point &max_p, const point & min_p, const vector<point> & aa, const vector<point> & bb) {
48 
49     int x, y;
50     int res = inf, temp = 0,ttu=inf;
51     for (x = min_p.x; x <= max_p.x; x++) {
52         for (y = min_p.y; y <= max_p.y; y++) {
53             temp = 0;
54             point tt = { x,y };
55             for (int i = 0; i <aa.size(); i++) {
56 
57                     temp +=dist(tt, aa[i]);
58             }
59                 ttu = inf;
60             for (int i = 0; i < bb.size(); i++) {
61             ttu= min(dist_sqrt(tt, bb[i]),ttu);
62             }
63              res = min(res, temp+ttu);
64         }
65     }
66     return res;
67 }
68 
69 int main() {
70 
71     int nn, mm, AA, BB;
72     int _case, cnt = 1;
73     vector<point> aa, bb;
74     scanf("%d", &_case);
75     for (cnt = 1; cnt <= _case; cnt++) {
76 
77        point  max_p = { 0,0 }, min_p = { inf,inf };
78         aa.clear(),bb.clear();
79         scanf("%d %d %d %d", &nn, &mm, &AA, &BB);
80         input(max_p, min_p, aa, AA);
81         input(max_p, min_p, bb, BB);
82         int res = work(max_p, min_p, aa, bb);
83 
84         printf("Case #%d: %dn", cnt, res);
85     }
86     //cin.get();
87     return 0;
88 }