• Gym


    pro:给定N个圆,求离原点最远的点,满足它在N个圆里。输出这个距离。N<50;

    sol:关键点一定是圆与圆的交点。 圆与 圆心到原点的直线 的交点。 然后去验证这些关键点是否在N个圆内。 实际操作的时候需要考虑一些条件:

    1,求圆的交点的时候,先判断是否内含或者相离。 

    2,求直线与圆的交点的时候,先判断是否圆心就在原点处。

    3,有可能不存在相交的圆。

    如何求圆与圆的交点:

    用atan2求出t,余弦定理求出a,即可。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=10010;
    const double eps=1e-8;
    const double pi=acos(-1.0);
    struct point{
        double x,y;
        point(){}
        point(double xx,double yy):x(xx),y(yy){}
    };
    struct Circle{
        point c;
        double r;
    };
    point operator +(point a,point b){ return point(a.x+b.x,a.y+b.y);}
    point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);}
    point operator *(point a,double p){return point(a.x*p,a.y*p);}
    point operator /(point a,double p){ return point(a.x/p,a.y/p);}
    double dot(point a,point b){ return a.x*b.x+a.y*b.y;}
    double det(point a,point b){ return a.x*b.y-a.y*b.x;}
    Circle C[maxn]; point P[maxn]; int tot,N; double ans1,ans2;
    void CirintersectCir(Circle A,Circle B)
    {
        point L=B.c-A.c;
        double dis=sqrt(dot(L,L));
        if(dis>A.r+B.r||fabs(A.r-B.r)>=dis+eps) return ;
        double angle1=atan2(L.y,L.x);
        double angle2=acos((A.r*A.r+dis*dis-B.r*B.r)/(2*A.r*dis));
        P[++tot]=point(A.c.x+A.r*cos(angle1+angle2),A.c.y+A.r*sin(angle1+angle2));
        P[++tot]=point(A.c.x+A.r*cos(angle1-angle2),A.c.y+A.r*sin(angle1-angle2));
    }
    void OtoCir(Circle A)
    {
        double dis=sqrt(dot(A.c,A.c));
        P[++tot]=A.c+A.c*A.r/dis;
    }
    int fcy=0; double R;
    bool check(point p)
    {
        rep(i,1,N)
          if(sqrt(dot(p-C[i].c,p-C[i].c))>C[i].r+eps) return false;
        if(fcy&&sqrt(dot(p,p))>R+eps) return false;
        return true;
    }
    int main()
    {
        scanf("%d",&N);
        rep(i,1,N){
             scanf("%lf%lf%lf",&C[i].c.x,&C[i].c.y,&C[i].r);
             if(C[i].c.x==0.0&&C[i].c.y==0.0) {
                if(fcy==0) fcy=1,R=C[i].r;
                else R=min(R,C[i].r);
                if(ans1==0) ans1=C[i].r;
                else ans2=min(ans2,C[i].r);
                i--; N--;
             }
        }
        if(fcy){
            Circle T; T.r=R; T.c.x=T.c.y=0;
            rep(i,1,N){
                P[++tot]=C[i].c/sqrt(dot(C[i].c,C[i].c))*R;
                CirintersectCir(T,C[i]);
            }
        }
        rep(i,1,N)
         rep(j,i+1,N)
          CirintersectCir(C[i],C[j]);
        rep(i,1,N) OtoCir(C[i]);
        rep(i,1,tot)
          if(check(P[i]))
            ans2=max(ans2,sqrt(dot(P[i],P[i])));
        if(ans2!=0.0) printf("%.3lf
    ",ans2);
        else printf("%.3lf
    ",ans1);
        return 0;
    }
  • 相关阅读:
    vim配置文件解析
    VIM使用技巧5
    补不manjaro系统
    linux下终端录制
    VIM的修炼等级
    VIM使用技巧4
    64位linux 汇编
    linux下编译安装gcc5.1
    Git学习笔记
    HTML实体符号代码速查表
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10700781.html
Copyright © 2020-2023  润新知