https://codeforces.com/gym/101955/problem/L
题意
给定一个圆C,半径为R,然后再给出n个圆C1,C2....Cn,这n个圆与圆C的交集部分被舍弃,问剩余部分的直径,
这个直径定义为最远距离的两点之间的距离。保证这n个圆互相之间不相交且没有一个覆盖掉整个圆C。
题解
直径只有两种情况:
1、过某一交点的且经过圆心的直径;
2、某两个交点组成的直径。
求出所有交点,然后check这些点关于原点对称的点是否不在所有n个圆里,如果是说明答案就是R*2;
否则暴力枚举所有交点构成的直径,检查合法性并更新答案即可。
1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 using namespace std; 5 const double Pi=acos(-1); 6 const double eps=1e-12; 7 const int N=1e5+5; 8 struct Point{ 9 double x,y; 10 Point(double x=0,double y=0):x(x),y(y){}; 11 }; 12 typedef Point Vector; 13 Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);} 14 Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);} 15 Vector operator *(Vector A,double B){return Vector(A.x*B,A.y*B);} 16 Vector operator /(Vector A,double B){return Vector(A.x/B,A.y/B);} 17 int dcmp(double x){ 18 if(fabs(x)<eps)return 0; 19 return x<0?-1:1; 20 } 21 bool operator<(const Point&a,const Point&b){return a.x<b.x||(a.x==b.x&&a.y<b.y);} 22 bool operator == (const Point &a,const Point &b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;} 23 double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;} 24 double Length(Vector A){return sqrt(Dot(A,A));} 25 double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;} 26 double Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));} 27 double Angle(Vector A) {return atan2(A.y, A.x);} 28 struct Circle{ //圆 29 Point c; 30 double r; 31 Circle(Point c = Point(0, 0), double r = 0):c(c),r(r){} 32 Point point(double a){ 33 return Point(c.x+cos(a)*r,c.y+sin(a)*r); 34 } 35 }; 36 double dis(Point A,Point B){ 37 return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); 38 } 39 int circle_circle(Circle C1,Circle C2,vector<Point>&sol){//圆与圆的交点 40 double d=Length(C1.c-C2.c); 41 if(dcmp(d)==0){ 42 if(dcmp(C1.r-C2.r)==0)return -1; 43 return 0; 44 } 45 if(dcmp(C1.r+C2.r-d)<0)return 0; 46 if(dcmp(fabs(C1.r-C2.r)-d)>0)return 0; 47 double a=Angle(C2.c-C1.c); 48 double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*d*C1.r)); 49 Point p1=C1.point(a-da),p2=C1.point(a+da); 50 sol.push_back(p1); 51 if(p1==p2)return 1; 52 sol.push_back(p2); 53 return 2; 54 } 55 int T,n; 56 double R; 57 Point p[N]; 58 double r[N]; 59 int check(Point A){ 60 for(int i=1;i<=n;i++){ 61 double h=dis(A,p[i]); 62 if(h<r[i]+eps)return 0; 63 } 64 return 1; 65 } 66 int main(){ 67 cin>>T; 68 int kase=0; 69 while(T--){ 70 cin>>n>>R; 71 Circle C0; 72 C0.c=Point(0,0); 73 C0.r=R; 74 vector<Point>v; 75 for(int i=1;i<=n;i++){ 76 double x,y,z; 77 scanf("%lf%lf%lf",&x,&y,&z); 78 p[i]=Point(x,y); 79 r[i]=z; 80 Circle C1; 81 C1.c=Point(x,y); 82 C1.r=z; 83 circle_circle(C0,C1,v); 84 } 85 double ans=0; 86 int f=0; 87 for(int i=0;i<v.size();i++){ 88 double x=-v[i].x; 89 double y=-v[i].y; 90 if(check(Point(x,y))){ 91 f=1; 92 break; 93 } 94 } 95 if(f||v.size()==0){ 96 printf("Case #%d: %.10lf ",++kase,R*2); 97 continue; 98 } 99 int h=v.size(); 100 for(int i=0;i<h;i++){ 101 for(int j=0;j<h;j++){ 102 if(i==j)continue; 103 double res=dis(v[i],v[j]); 104 ans=max(ans,res); 105 } 106 } 107 printf("Case #%d: %.10lf ",++kase,ans); 108 } 109 }