博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[扫描线]POJ2932 Coneology
阅读量:4349 次
发布时间:2019-06-07

本文共 1962 字,大约阅读时间需要 6 分钟。

题意:有n个圆 依次给了半径和圆心坐标  保证输入的圆不相交(只有 相离 和 内含/外含 的情况)

     问 有几个圆 不内含在其他圆中,并分别列出这几个圆的编号(1~n)

    (n的范围是[1, 40000])

案例画出来大概是这样的

(那个原点为(50,50)的太远了,就意思一下)

 

所以答案是3号圆和5号圆 不被包含

 

 

好了,若这道题n只有1000,那么只要for两层,每个圆与另外的圆比较, 判断圆心是否在其他圆内即可判断是否包含

这样的复杂度是O($n^2$)

 

可是现在n有40000,显然不能用O($n^2$)来解决

由这道题,简单粗暴的学习了一下扫描线, 复杂度为O(nlogn)

 

什么是扫描线呢?

顾名思义,就是一根线,扫描过去。

怎样的一根线,怎么扫过去呢?

①平行于x轴,自上而下/自下而上 扫描

②平行于y轴,自左而右/自右而左 扫描

③绕圆心 逆时针/顺时针 扫描

扫描线要干什么呢?

“扫描线在平面上按给定轨迹移动的同时,不断根据扫描线扫过部分更新信息,从而得到整体所要求的结果”

 

 

这道题,可以用上述的①/②

 

 自左而右扫描时,只有当扫描线移动到圆的左右两端时,线与圆的关系才会发生改变,因此先把圆的左右端点取出来排个序

 

每当遇到某圆的左端点,判断该圆是否包含在其他圆内

因为所有的圆都不相交,因此,每个圆都只可能包含在上下两个与它最相近的圆中

(此处“上下两个”是通过比较 圆心的纵坐标 来确定的)

 

也就是 每当我们得到一个不包含在其他圆中的圆,我们需要将它存起来,并将这些圆按圆心的纵坐标排序 以便与下一个扫到的圆进行比较

我们可以用set<pair<double, int> >来存 (pair.first是圆心的纵坐标,pair.second是圆的编号) set会自动按pair.first排序

 

当我们扫到某圆的右端点时,表示该圆的影响范围已经扫完了,后面扫到的圆不可能包含在该圆中,因此可以把该圆从set中去掉

 

查找“上下两个与它最近的圆”的复杂度为O(logn) 

因此遍历n个圆的复杂度为O(nlogn)

 

1 const int N=40005; 2  3 double x[N], y[N] ,r[N]; 4  5 bool inside(int i, int j) // i是否在j内 6 { 7     double dx=x[i]-x[j], dy=y[i]-y[j]; 8     return dx*dx+dy*dy<=r[j]*r[j]; 9 }10 11 int main()12 {13     int n;14     while(~scanf("%d", &n))15     {16         for(int i=0;i
> X;19 for(int i=0;i
> out;26 vector
ans;27 for(int i=0;i
>::iterator it=out.lower_bound(make_pair(y[id], id));33 if(it!=out.end() && inside(id, it->second)) // id 在 前一个圆内 不加入34 continue;35 if(it!=out.begin() && inside(id, (--it)->second)) // id 在 后一个圆内 不加入36 continue;37 ans.push_back(id);38 out.insert(make_pair(y[id], id));39 }40 else // 右41 out.erase(make_pair(y[id], id));42 }43 sort(ans.begin(), ans.end());44 printf("%d\n", ans.size());45 for(int i=0;i
POJ 2932

 

转载于:https://www.cnblogs.com/Empress/p/4643074.html

你可能感兴趣的文章
多维表头的DataGridView
查看>>
github安装k8s
查看>>
c++之map函数/迭代器
查看>>
FFmpeg RTSP流通过UDP传输问题
查看>>
堆,二分,尺取
查看>>
Introduction to Rotary Cement Wet Kilns
查看>>
Scala:字符串高级应用
查看>>
node,Yeoman,Bower,Grunt的简介及安装
查看>>
解决虚拟机 正在决定eht0 的ip信息失败 无链接-- 虚拟机上linux redhat 上网问题
查看>>
一些资源地址
查看>>
[LeetCode] Reverse Words in a String II
查看>>
VC在windows中打开文件夹并选中文件
查看>>
一.web服务机制
查看>>
使用TransactionScope做分布式事务协调
查看>>
黑马程序员---反射笔记
查看>>
使用SQL Server 2008 维护计划(图解)
查看>>
点击链接弹出框提示《转》
查看>>
xpath提取多个标签下的text
查看>>
Oracle expdb异地备份
查看>>
编程学习网站
查看>>