2018-2019 ACM-ICPC, Asia Shenyang Regional Contest L. Machining Disc Rotors(计算几何)

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\n",++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\n",++kase,ans);
108     }
109 }

 

posted @ 2019-09-23 15:45  Venux  阅读(407)  评论(0编辑  收藏  举报