zoukankan      html  css  js  c++  java
  • 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
    ",++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 }
  • 相关阅读:
    简易自制线程池(备忘)
    大数据量的删除过程查看
    收集书籍备忘
    6月12日C代码
    fseek()
    区分int *p[4]与int (*p)[4]
    常用的字符串处理函数 C语言
    6月11日
    C学习代码
    文件读取 C语言
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/11572717.html
Copyright © 2011-2022 走看看