【模板】 计几平面最近圆对
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3124
思路:二分答案,每个圆扩大len,找到最大使得所有圆都不想交的len即可。用到了扫描线,x轴排序,y轴用set维护。
参考了博客:https://blog.csdn.net/morejarphone/article/details/50114867
也不知道为什么删除的时候哦还要查看一边有没有相交。。。。。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 5e4+9; 4 #define eps 1e-8 5 #define pii pair<double,int> 6 struct Circle{ 7 double x,y,r; 8 }p[N],tp[N]; 9 pii L[N*3]; 10 int n; 11 bool inter(Circle a,Circle b){ 12 double dis = sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) ); 13 return dis - a.r - b.r <= eps; 14 } 15 bool judge(double len){ 16 int cnt =0; 17 for(int i = 1;i<=n;++i){ 18 tp[i] = p[i]; 19 tp[i].r += len; 20 L[++cnt] = make_pair( tp[i].x - tp[i].r,i); 21 L[++cnt] = make_pair( tp[i].x + tp[i].r,i+n); 22 } 23 sort(L+1,L+1+cnt); 24 set< pii > st; 25 for(int i = 1;i<=cnt;++i){ 26 int id = L[i].second; 27 if(id <= n){ 28 set< pii >::iterator it = st.lower_bound( make_pair(tp[id].y,id) ); 29 if( it != st.end() ){ 30 int tid = it->second; 31 if( inter(tp[id],tp[tid]) ) return 0; 32 } 33 if( it != st.begin() ){ 34 --it; int tid = it->second; 35 if( inter(tp[id],tp[tid]) ) return 0; 36 } 37 st.insert( make_pair(tp[id].y,id) ); 38 } 39 else st.erase( make_pair(tp[id-n].y,id-n) ); 40 } 41 return 1; 42 } 43 int main(){ 44 int T; scanf("%d",&T); 45 while(T--){ 46 scanf("%d",&n); 47 for(int i = 1; i<=n;++i) scanf("%lf %lf %lf",&p[i].x,&p[i].y,&p[i].r); 48 double ans,l=0,r=1000000; 49 while(r-l >= eps){ 50 double m = (l+r)/2; 51 if(judge(m)){ 52 l = m; 53 ans = m; 54 } 55 else r = m; 56 } 57 printf("%lf\n",ans*2); 58 } 59 return 0; 60 }