UVALIVE 3954 Phone Cell <离散化 + 圆相交关系〉
2016-07-16 19:31
295 查看
题目:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1955
题意:如今时代,手机打电话,需要BTS信息收发电台发射信号,呈圆形发布。给你手机的坐标,发射范围为r,求出一台发射器覆盖手机数最多多少?
知识点:数学,离散化,坐标转换,极坐标
问题分析:这道题,由于圆心不知道,一开始,可能会想到模拟退火算法,然而这道题没有给x,y的坐标范围,不能使用。最终采用离散化
解题思路:每一个点分别作为极坐标原点,然后一一取其他求圆心极坐标角度范围,求出重合区间最多多少个,个数既是ans,取最大,最终结果就是max(ans+1)
时间复杂度:n^2logn
暑假这么热,每天热得不想起床,今早又逃课了。。。老衲罪过罪过
补充一下:
如上图,设A、B为点集中的两个点, 分别以A、B为圆心作单位圆,则相交范围内的任意位置作新的单位圆,都可以同时包含A与B,如圆C,如果把C放在一个其中一个圆A的圆周上,则圆C的圆周会穿过点A。
假设已得到题目的一个解圆O,则把得到的圆O通过移动,总可以让圆内的某个点X靠在圆周上,换言之,O也在X所作单位圆的圆周上。
由此,可枚举在最终结果的圆周上的点X,目标圆心O在X的圆周上。
每枚举一个X作为图中的点A,枚举其他所有点作为点B,可得到C对应点A、B的在A圆周上的一个范围,覆盖次数最多的那个范围就是当X作为点O圆周上的点所能得到的最优解O的范围,这个次数加1(点X)就是对应X的最优解。
通过枚举所有X,更新出最优解。
覆盖范围可以用圆周角表示,则为区间覆盖问题。
题意:如今时代,手机打电话,需要BTS信息收发电台发射信号,呈圆形发布。给你手机的坐标,发射范围为r,求出一台发射器覆盖手机数最多多少?
知识点:数学,离散化,坐标转换,极坐标
问题分析:这道题,由于圆心不知道,一开始,可能会想到模拟退火算法,然而这道题没有给x,y的坐标范围,不能使用。最终采用离散化
解题思路:每一个点分别作为极坐标原点,然后一一取其他求圆心极坐标角度范围,求出重合区间最多多少个,个数既是ans,取最大,最终结果就是max(ans+1)
时间复杂度:n^2logn
暑假这么热,每天热得不想起床,今早又逃课了。。。老衲罪过罪过
#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> #include <algorithm> #define eps 1e-9 #define PI acos(-1.0) using namespace std ; struct Point { double x,y; } pt[2005]; struct Node { double angle; int flag; } node[10005]; bool cmp(const Node& a,const Node& b) { if(a.angle - b.angle >-eps && a.angle - b.angle < eps) return a.flag > b.flag; return a.angle < b.angle; } double dist(Point& a,Point& b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } int main() { int n,m; while(scanf("%d %d",&n,&m) == 2&&n) { int i,j; for(i=0; i<n; i++) { scanf("%lf %lf",&pt[i].x,&pt[i].y); } double d; double temp,an; int ans = 0,sum,k; for(i=0; i<n; i++) { k = 0; for(j=0; j<n; j++) { if(i == j) continue; d = dist(pt[i],pt[j]); if( d - 2*m > eps ) continue; an = atan2(pt[j].y - pt[i].y,pt[j].x - pt[i].x); if(an < 0) an += 2*PI; temp = acos(d/2.0/m); node[k].angle = an - temp + 2*PI; node[k].flag = 1; k++; node[k].angle = an + temp + 2*PI; node[k].flag = -1; k++; } sum = 0; sort(node,node+k,cmp); for(j=0; j<k; j++) { ans = max(ans,sum += node[j].flag); } } printf("It is possible to cover %d points.\n",ans + 1); } return 0; }
补充一下:
如上图,设A、B为点集中的两个点, 分别以A、B为圆心作单位圆,则相交范围内的任意位置作新的单位圆,都可以同时包含A与B,如圆C,如果把C放在一个其中一个圆A的圆周上,则圆C的圆周会穿过点A。
假设已得到题目的一个解圆O,则把得到的圆O通过移动,总可以让圆内的某个点X靠在圆周上,换言之,O也在X所作单位圆的圆周上。
由此,可枚举在最终结果的圆周上的点X,目标圆心O在X的圆周上。
每枚举一个X作为图中的点A,枚举其他所有点作为点B,可得到C对应点A、B的在A圆周上的一个范围,覆盖次数最多的那个范围就是当X作为点O圆周上的点所能得到的最优解O的范围,这个次数加1(点X)就是对应X的最优解。
通过枚举所有X,更新出最优解。
覆盖范围可以用圆周角表示,则为区间覆盖问题。
相关文章推荐
- 客户端C和服务器S之间建立了一个TCP连接,TCP最大段长度为1KB,客户端C当前的拥塞窗口是16KB,向服务器S连续发送2个最大段之后,成功收到服务器S发送的第一段的确认段,确认段中通告的接受窗口大
- photoshop常用快捷键汇总
- Android 中this的用法
- 文件操作II
- 泛型
- Java反射Class.forName()配置文件演示
- 自定义Toast的显示时长
- iOS 判断 当前ViewController是否正在显示
- 算法日记(Java实现)第20160716(2)期——POJ1003/POJ1004
- leetcode_c++:链表:Rotate List(061)
- hibernate学习 hibernate-tutorials(一)——basic
- html a标签中调用js的几种方法
- 快速排序_泰山鲁用村里抢媳妇的故事说明这个算法
- 16. 3Sum Closest
- ROS学习之 roslaunch
- 【字符串】C++字符串编程小结
- 已知一对夫妇有两个孩子,如果知道有一个是男孩,那么两个都是男孩的概率?
- HDU 5319 Painter(暴力枚举)
- 通讯录
- BigInteger和BigDecimal大数相加问题