POJ 2932 Coneology计算最外层圆个数

平面上有n个两两没有公共点的圆,i号圆的圆心在(xi,yi),半径为ri,编号从1开始。求所有最外层的,即不包含于其他圆内部的圆。输出符合要求的圆的个数和编号。n<=40000.

(注意此题无相交相切!!!)
工具:扫描线+set

中心思想:
边界分左右端点,如图,当扫描线与k号圆左端点相切,之前用set维护一个y纵坐标的二叉树,那我们在二叉树中查找离k号圆纵坐标最近的上下两个圆(A,B),让k与A,B判是否内含即可,为什么是AB?假设有C点(离k远一些)包含k,但A不包含k,那么一定有A,C相交,这不符合题意。
之后,当扫到右端点,从set中删掉这个圆(即图中的D,因为它对后面k的判断没卵关系,而且还可能阻碍A,B)

上代码:

typedef pair<double,int>P;

struct node{
double x,y,r;
}nod;

bool inside(int a,b){//判断a是否在b中,半径大于圆心距
double dx=node[a].x-node[b].x,dy=node[a].y-node[b].y;
return dx*dx+dy*dy-node[b].r*node[b].r<=eps;
}

void solve(){
vector<P>point;
set<P>outer;//记录与当前扫描线相交的最外层圆集合
vector<int>ans;//真正存储最外层圆集合
For(i,1,n){
point.pb(P(nod[i].x-nod[i].r,i));//记录左端点
point.pb(P(nod[i].x+nod[i].r,i+n));//记录右端点
}
sort(point+1,point+1+n);
For(i,0,point.size()-1){
int id=point[i].sd;
if(point[i].sd<n){//扫到左端点
set<P>::iterator it=outer.lower_bound(P(nod[id].y,id));//二分找A,B
if(it!=outer.begin()&&inside(id,it->sd))continue;
if(it!=outer.end()&&inside(id,(--it)->sd))continue;
ans.pb(P(nod[id].y,id));
outer.insert(P(nod[id].y,id));
}else outer.erase(P(node[id].y,id));   //扫到右端点,删掉
}
sort(ans.begin(),ans.end());

原文地址:https://www.cnblogs.com/planche/p/9420516.html

时间: 2024-10-10 23:03:02

POJ 2932 Coneology计算最外层圆个数的相关文章

POJ 2932 Coneology (平面扫描)

Coneology Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3713   Accepted: 720 Description A student named Round Square loved to play with cones. He would arrange cones with different base radii arbitrarily on the floor and would admire

POJ 2932 Coneology(扫描线)

[题目链接] http://poj.org/problem?id=2932 [题目大意] 给出N个两两没有公共点的圆,求所有不包含于其它圆内部的圆 [题解] 我们计算出所有点在圆心所有y位置的x值, 由于两两没有公共点,所以当我们对所有的x坐标进行扫描时,只要扫描相邻的x, 判定扫描到的圆和与其x相邻的圆是否是圆包含关系就可以判断一个圆的位置 扫描到左端点时,如果圆其被包含,则什么都不做,否则,将这个圆加入set中, 当扫描到右端点时,如果圆被包含,则什么都不做,否则将圆从set中去除. [代码

poj 2932 Coneology (扫描线)

题意 平面上有N个两两不相交的圆,求全部最外层的,即不被其它圆包括的圆的个数并输出 思路 挑战程序竞赛P259页 代码 /* ********************************************** Auther: xueaohui Created Time: 2015-7-25 16:56:13 File Name : poj2932.cpp *********************************************** */ #include <iostr

poj 2932 Coneology(扫描线+set)

Coneology Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3574   Accepted: 680 Description A student named Round Square loved to play with cones. He would arrange cones with different base radii arbitrarily on the floor and would admire

poj 2932 Coneology 扫面线法

题意: 给n个无交点的圆,求这n个圆中不被其它圆包含的圆. 分析: 扫面线法,用二叉树(set+lowerbound方法)维护最外圆的集合. 代码: #include <iostream> #include <algorithm> #include <vector> #include <set> using namespace std; const int maxN=40012; double r[maxN],x[maxN],y[maxN]; int n;

计算建立对象的个数

1.程序设计思想 定义一个静态字段,在构造函数中写一个这个静态字段自加的语句,这样,因为静态字段不会因为再次调用而改变数值所以可以计算建立对象的个数. 2.程序源代码 class sum{ public static int a=0; int b; public sum(int b1) { b=b1; a++; } public int get() { return a; } } public class Ccj{ public static void main(String[] args) {

POJ 1284 Primitive Roots (求原根个数)

Primitive Roots 题目链接:http://poj.org/problem?id=1284 利用定理:素数 P 的原根的个数为euler(p - 1) typedef long long ll; using namespace std; /* 求原根 g^d ≡ 1(mod p) 其中d最小为p-1,g 便是一个原根 复杂度:O(m)*log(P-1)(m为p-1的质因子个数) */ ll euler(ll x) { ll res = x; for (ll i = 2; i <= x

计算形状Shape(圆Circle,矩形Square ,正方形Rectangle)的面积、周长

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _计算形状 { class Program { static void Main(string[] args) { //作业:计算形状Shape(圆Circle,矩形Square ,正方形Rectangle)的面积.周长 Shape shape =

poj 1845 Sumdiv (算术基本定理求一个数因子和)

求一个数的所有因子和可以用算术基本定理,下面是它的两个重要应用: (1)一个大于1的正整数N,如果它的标准分解式为: N=(P1^a1)*(P2^a2)......(Pn^an) 那么它的正因数个数为(1+a1)(1+a2).....(1+an). (2) 它的全体正因数之和为d(N)=(1+p1+...p1^an)(1+p2+...p2^a2)...(1+pn+...+pn^an) 和求一个数正因数个数的方法类似. 可以先打表出sqrt(n)以内的所有素数(当然也可以不打表),因为n的素因数中