1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include<bits/stdc++.h> using namespace std; typedef double db; #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) template <class T> inline void cmin(T &a,const T &b){ ((a>b)&&(a=b)); } template <class T> inline void cmax(T &a,const T &b){ ((a<b)&&(a=b)); }
const int N=110; const db eps=1e-10,Pi=acos(-1),D=2*Pi;
int n; struct Cir{ int x,y,r; }A[N];
db X[N],Y[N],H[N]; int C,S[N]; db Norm(db x){ return x<0?x+D:x; } int I(db x){ return lower_bound(H+1,H+C+1,x)-H; }
int Check(db L){ memset(S,0,sizeof S); H[1]=0,H[C=2]=D; rep(i,1,n) { db dis=A[i].x*A[i].x+A[i].y*A[i].y; db t=sqrt(dis-A[0].r*A[0].r)-A[i].r; dis=sqrt(dis); if(dis-A[0].r-A[i].r>=L){ X[i]=0,Y[i]=D; continue; } db l,r; if(t>=L) { db a=dis,b=A[0].r,c=L+A[i].r; db co=(a*a+b*b-c*c)/(2*a*b); db x=acos(co),y=atan2(A[i].y,A[i].x); l=y+x,r=y-x+D; } else { db d=acos(A[0].r/dis); db x=atan2(A[i].y,A[i].x); db y=(L-t)/A[0].r+d; if(y>Pi) return 0; l=x+y,r=x-y+D; } if(r>D) l-=D,r-=D; if(r<=0) l+=D,r+=D; H[++C]=Norm(X[i]=l),H[++C]=Y[i]=r; }
sort(H+1,H+C+1); rep(i,1,n) { if(X[i]>=0) S[I(X[i])]++,S[I(Y[i])]--; else S[I(0)]++,S[I(Y[i])]--,S[I(X[i]+D)]++,S[I(D)]--; } rep(i,1,C) if((S[i]+=S[i-1])==n) return 1; return 0; }
class CircusTents { public: double findMaximumDistance(vector <int> _x, vector <int> _y, vector <int> _r) { n=_x.size()-1; rep(i,0,n) A[i]=(Cir){_x[i]-_x[0],_y[i]-_y[0],_r[i]};
db l=0,r=1e5; while(r-l>eps) { db mid=(l+r)/2; if(Check(mid)) l=mid; else r=mid; } return l; } };
|