POJ 2932 Coneology(扫描线)

Posted forever97‘s blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2932 Coneology(扫描线)相关的知识,希望对你有一定的参考价值。

 

【题目链接】 http://poj.org/problem?id=2932

 

【题目大意】

  给出N个两两没有公共点的圆,求所有不包含于其它圆内部的圆

 

【题解】

  我们计算出所有点在圆心所有y位置的x值,
  由于两两没有公共点,所以当我们对所有的x坐标进行扫描时,只要扫描相邻的x,
  判定扫描到的圆和与其x相邻的圆是否是圆包含关系就可以判断一个圆的位置
  扫描到左端点时,如果圆其被包含,则什么都不做,否则,将这个圆加入set中,
  当扫描到右端点时,如果圆被包含,则什么都不做,否则将圆从set中去除。

 

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int MAX_N=40010;
int N;
double x[MAX_N],y[MAX_N],r[MAX_N];
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];
}
void solve(){
    vector<pair<double,int> >events;
    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<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‘:‘ ‘);
    }
}
void init(){
    for(int i=0;i<N;i++)scanf("%lf%lf%lf",&r[i],&x[i],&y[i]);
}
int main(){
    while(~scanf("%d",&N)){
        init();
        solve();
    }return 0;
}

  

以上是关于POJ 2932 Coneology(扫描线)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2932 Coneology (平面扫描)

刷题总结——coneology(poj2932 扫描线)

POJ-2932 Coneology[平面扫描]

POJ 2932 Coneology (平面扫描)

POJ 2932 Coneology(扫描线)

POJ 2932 Coneology计算最外层圆个数