Coneology POJ - 2932(平面扫描+二叉搜索树)

传送门

题意:平面上有N个两两都没有公共点的圆,i号圆的圆心在(xi,yi),半径为ri。求所有最外层的,即不包含于其他圆内部的圆。

题解:

附上代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>

using namespace std;

int N;
double x[50005],y[50005],r[50005];

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':' ');
    }
}

int main()
{
    while(scanf("%d",&N)!=EOF){
        for(int i=0;i<N;i++){
            scanf("%lf%lf%lf",&r[i],&x[i],&y[i]);
        }
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/83075022