扫描线POJ2932
来源:互联网 发布:silverlight mac 卸载 编辑:程序博客网 时间:2024/05/22 00:42
思路转自 http://www.cppblog.com/Wangzhihao/articles/109348.html
考虑扫描线,选择一个圆的最左点和最右点作为事件点.然后用一条竖直线从左到右扫一遍.
维护一个数据结构,里面保存着和扫描线相交的powerful 圆.
如果一个事件是某圆的最右点,并且该圆在数据结构中,就意味着要把这个圆删掉.
如果一个事件是某圆的最左点,当它不被其他圆包含时,就意味着可能要把它加入到我们的数据结构中,
怎么检查它有没有被其他圆包含呢?我们的数据结 构里的圆都是一些 powerful 圆,他们互不相交,也就是
说他们在当前的扫描线上占的区间也互不相交, 如果我们只是记录圆心在扫描线的投影, 把高的投影称为前,
把低的投影低称为后,那么可能与当前圆发生关系的只是它的前一个圆,后一个圆.
考虑扫描线,选择一个圆的最左点和最右点作为事件点.然后用一条竖直线从左到右扫一遍.
怎么检查它有没有被其他圆包含呢?我们的数据结 构里的圆都是一些 powerful 圆,他们互不相交,也就是
说他们在当前的扫描线上占的区间也互不相交, 如果我们只是记录圆心在扫描线的投影, 把高的投影称为前,
把低的投影低称为后,那么可能与当前圆发生关系的只是它的前一个圆,后一个圆.
//平面上N个两两没有公共点的圆,i号圆的圆心在(xi,yi)半径ri,求所有最外层,不包含在其他圆内部的圆 //如果用圆心检测的话复杂度为O(N*N) //平面扫描技术可以降低算法的复杂度,就是查看当前扫面线经过的圆左侧的时候,Y坐标上相邻最近的两个圆 #include <cstdio.h>#include <iostream> #include <algorithm> #include <vector> #include <set> #include <utility> using namespace std; #define MAX_N 40006 static int N; static double x[MAX_N],y[MAX_N],r[MAX_N]; //判断圆i是否在圆j的内部 static bool inside(int i,int j){ double dx =x[i] - x[j],dy = y[i] - y[j]; return dx*dx + dy*dy <=r[j]*r[j]; } //枚举关键点 static void solve(){ vector<pair<double,int> >events;//圆的左右两端的x坐标 for (int i=0;i<N;++i) { events.push_back(make_pair(x[i]-r[i],i)); events.push_back(make_pair(x[i]+r[i],i+N)); } sort(events.begin(),events.end()); //平面扫描 //注意有个特殊情况: //就是新要插入的点,如果纵坐标,和set内部的某个正在集合中的圆的坐标相等,那么一定有这个新圆在其内部 set<pair<double,int> >outers;//与扫描线相交的最外层圆的集合 vector<int>res;//最外层的圆列表 for (int i=0;i<events.size();++i) { int id = events[i].second%N; if (events[i].second<N)//扫描的左端 { set<pair<double,int> >::iterator it = outers.lower_bound(make_pair(y[id],id)); if (it!=outers.end()&&inside(id,it->second)) continue; if (it!=outers.begin()&&inside(id,(--it)->second)) continue; res.push_back(id); outers.insert(make_pair(y[id],id)); } else outers.erase(make_pair(y[id],id)); } sort(res.begin(),res.end()); printf("%d\n",res.size()); for (int i=0;i<res.size();++i) { printf("%d%c",res[i]+1,i+1==res.size()?'\n':' '); } } int main(){ scanf("%d",&N); for (int i=0;i<N;++i) { scanf("%lf %lf %lf",&r[i],&x[i],&y[i]); } solve(); return 0; }
0 0
- POJ2932 扫描线
- 扫描线POJ2932
- poj2932(几何扫描线)
- poj2932:Coneology(扫描线)
- poj2932 Coneology【扫描线+set】
- POJ2932
- poj2932
- POJ2932
- POJ2932:Coneolog
- Coneology(poj2932)
- 扫描线
- 扫描线
- 扫描线
- 扫描线
- 扫描线
- 扫描线
- 多边形扫描线算法
- HDU 4007 线扫描
- NYOJ 1057 寻找最大数(三)贪心算法
- Java的类
- C#控制台基础 string字符串的连接
- Assertion failure in -[UITableView _dequeueReusableViewOfType:withIdentifier:], /BuildRoot/Library/C
- Builder Pattern(建造者模式)
- 扫描线POJ2932
- Dubbo并发控制
- Android中两个Activity之间数据传递及返回
- OpenGL 纹理坐标 和 顶点坐标映射关系 详解
- Built-in functions for atomic memory access
- windows平台安装mysql-5.7.14-winx64
- 指针的概念以及一些小秘密
- Shell脚本读取mysql结果集各数据项的值
- uva11729突击战!!!