题目链接:http://poj.org/problem?id=2932
详细题解:因为题目内的圆不存在相交的情况, 直接把储存每个圆的左端点和右端点的x坐标。然后从左扫到右,如果满足是最外面的圆,就储存在set里面。如何判断满足,就是对每一个x,如果是左端点的x坐标就来判断其对应的圆,是否是在set中储存的圆内,如果不是 ,就存到set中。如果是右端点的x坐标,就pop出该圆。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#define N 41000
using namespace std;
int n;
double x[N], y[N], r[N];
vector<pair<double,int> > events;
bool slove(int i, int j){
double dx = x[i]-x[j];
double dy = y[i]-y[j];
return dx*dx+dy*dy <= r[j]*r[j];
}
int main ()
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%lf %lf %lf", &r[i], &x[i], &y[i]);
events.push_back(make_pair<double, int>(x[i]-r[i], i));
events.push_back(make_pair<double, int>(x[i]+r[i], i+n));
}
sort(events.begin(), events.end());
set<pair<double, int> > outers;
vector<int>ans;
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() && slove(id, it->second)) continue;
if(it != outers.begin() && slove(id, (--it)->second)) continue;
ans.push_back(id);
outers.insert(make_pair(y[id], id));
}
else{
outers.erase(make_pair(y[id], id));
}
}
sort(ans.begin(), ans.end());
int len = ans.size();
printf("%d\n", len);
for(int i = 0; i < len; i++)
{
if(i == 0) printf("%d", ans[i]+1);
else printf(" %d", ans[i]+1);
}
puts("");
return 0;
}