2015编程之美资格赛 C 基站选址
来源:互联网 发布:最新炒股软件排名 编辑:程序博客网 时间:2024/04/30 15:28
- 样例输入
23 3 4 11 22 12 33 22 24 4 4 21 22 43 14 31 41 3
- 样例输出
Case #1: 4Case #2: 13
描述
需要在一个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.解题思路:本题要求找一个合适的位置建立一个基站,使得总费用最小。根据题意描述,费用包含两个部分,第一部分是用户到基站的欧几里得距离的平方,第二个是到最近的通讯公司的曼哈顿距离。不难想象,这个基站的位置应该大致处于n个用户中间的区域。其实,可以通过列式推导出最合适的位置的大致区域。
首先考虑用户的距离之和d1=sum{(x-xi)^2}+sum{(y-yi)^2},如果距离达到最小,那么该点一定是一个极小值点。根据高等数学的知识,该处的偏导数都为0,。因此可以事先对x,y求偏导。发现,x=sum{xi}/n,y=sum{yi}/n,因此可以对该点以及周围的8个点进行搜索。那么曼哈顿距离此时是否为最小呢?不难发现,曼哈顿距离的改变量每移动一格只会变化最多一个距离,但欧几里得距离最大的变化量会大于1个距离单位,因此应该尽量保证d1达到最小。
因此,只需要在平均值以及其周围的8个点中找出总距离最小的,就是最终的结果了。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream>#include<algorithm>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<functional>using namespace std;#define mxn 200005#define LL long long#define MP make_pair#define REP(i, a, b) for (int i = a; i <= b; ++i)#define FOR(i, a, b) for (int i = a; i < b; ++i)int dx[] = { 0, 0, 0, 1, 1, 1, -1, -1, -1 };int dy[] = { 0, 1, -1, 0, 1, -1, 0, 1, -1 };LL ABS(LL x) {return x < 0 ? -x : x;}struct point {LL x, y;//考虑到大数据范围,选用long longpoint(){};point(LL x, LL y) :x(x), y(y){}point operator - (const point& b) const //重载减号,方便输入{return point(x - b.x, y - b.y);}void input() {cin >> x >> y;}LL dis() //欧几里得距离的平方{return x * x + y * y;}LL len() //曼哈顿距离{return ABS(x) + ABS(y);}}A[1005], B[105];LL cal(point o, int a, int b) //计算(a,b)点出的总距离{LL ret = ~0uLL >> 1;REP(i, 1, b) ret = min(ret, (o - B[i]).len());REP(i, 1, a) ret += (o - A[i]).dis();return ret;}int main(){//freopen("t.txt", "r", stdin);int t, n, m, a, b, cas = 0;cin >> t;while (t--) {cin >> n >> m >> a >> b;REP(i, 1, a) A[i].input();REP(i, 1, b) B[i].input();LL ans = ~0uLL >> 1, x = 0, y = 0;REP(i, 1, a) x += A[i].x, y += A[i].y;x /= a, y /= a;//求平均值FOR(k, 0, 9) //在平均值及其附近的8个点中找到最小距离{LL tx = x + dx[k], ty = y + dy[k];if (tx < 1 || tx > n || ty < 1 || ty > m) continue;//出界ans = min(ans, cal(point(tx, ty), a, b));}cout << "Case #" << ++cas << ": " << ans << endl;}return 0;}
- 2015编程之美资格赛 C 基站选址
- 编程之美2015资格赛 C 基站选址 (数学)
- 编程之美2015资格赛 C.基站选址
- 2015编程之美资格赛:基站选址 暴力
- 编程之美2015资格赛 题目3 : 基站选址
- 【编程之美2015资格赛】基站选址(数学题)
- 2015编程之美资格赛题目3 : 基站选址
- hihocoder 2015编程之美 资格赛 hihocoder 第三题 基站选址
- hiho 编程之美2015资格赛(基站选址-绝对值方程分段)[WA]
- 编程之美2015资格赛 - 题目3 : 基站选址(三分)
- 2015编程之美 基站选址
- 编程之美2015资格赛
- 编程之美2015资格赛
- 编程之美2015资格赛
- 编程之美资格赛
- 编程之美资格赛
- 编程之美2015资格赛之2.29
- 2015编程之美资格赛A
- chromium浏览器开发系列第四篇:如何调试最新chromium源码
- 第三章第11题
- 最受HR欢迎的简历五大特征
- KLEE on Ubuntu 12.04 LTS 64Bit
- Java NIO与IO
- 2015编程之美资格赛 C 基站选址
- XAMPP禁止目录浏览的方法
- 小菜学Chromium之OpenGL学习之二
- golang 断言 + 类型转换
- Log4Net使用
- 从Java转iOS第一个项目总结(来源:蛙牛的博客)
- C#中委托的调用
- hdu2059 龟兔赛跑 (还没做)
- 反尼姆游戏