题意:
给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;
vector<pair<double,int> > events;
set<pair<double,int> > outers;
vector<int> res;
bool inside(int i,int j)
{
double dx=x[i]-x[j],dy=y[i]-y[j],dr=r[i]-r[j];
return r[i]<=r[j]&&dx*dx+dy*dy<=dr*dr;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%lf%lf%lf",&r[i],&x[i],&y[i]);
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());
for(int i=0;i<events.size();++i){
int ids=events[i].second%n;
if(events[i].second<n){
set<pair<double,int> >::iterator it=outers.lower_bound(make_pair(y[ids],ids));
if(it!=outers.end()&&inside(ids,it->second)) continue;
if(it!=outers.begin()&&inside(ids,(--it)->second)) continue;
res.push_back(ids);
outers.insert(make_pair(y[ids],ids));
}else
outers.erase(make_pair(y[ids],ids));
}
sort(res.begin(),res.end());
printf("%d\n",res.size());
for(int i=0;i<res.size();++i)
printf("%d ",res[i]+1);
return 0;
}
本文介绍了一种使用扫描线法和二叉树维护最外圆集合的方法来解决给定无交点圆集的问题,具体阐述了算法流程、核心逻辑以及代码实现细节。
535

被折叠的 条评论
为什么被折叠?



