2932(平面掃描+二叉搜尋樹)
阿新 • • 發佈:2018-12-15
題意:平面上有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; }