##Luogu2533[AHOI2012]信号塔

Luogu2533[AHOI2012]信号塔

题面:洛谷

解析

博主最近在补计算几何,所以做了这道最小圆覆盖板题话说最小圆覆盖的复杂度为什么是\(O(n)\)的啊

代码


// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
#define gc() getchar()
inline int In(){
    char c=gc(); int x=0,ft=1;
    for(;c<'0'||c>'9';c=gc()) if(c=='-') ft=-1;
    for(;c>='0'&&c<='9';c=gc()) x=x*10+c-'0';
    return x*ft;
}
const double eps=1e-6,Pi=acos(-1.0);
inline int dcmp(double x){
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}
struct Point{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
}p[N];
typedef Point Vector;
Vector operator + (Vector a,Vector b){ return Vector(a.x+b.x,a.y+b.y); }
Vector operator - (Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
Vector operator * (Vector a,double p){ return Vector(a.x*p,a.y*p); }
Vector operator / (Vector a,double p){ return Vector(a.x/p,a.y/p); }
inline double Dot(Vector a,Vector b){
    return a.x*b.x+a.y*b.y;
}
inline double Cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}
inline double Len(Vector a){
    return sqrt(Dot(a,a));
}
inline Vector Rotate(Vector a,double rad){
    return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}
inline Point GetLineintersection(Point p,Vector v,Point q,Vector w){
    Vector u=p-q;
    double t=Cross(w,u)/Cross(v,w);
    return p+v*t;
}
inline Point Get_c(Point a,Point b,Point c){
    Point p=(a+b)/2.0,q=(b+c)/2.0; Vector v=Rotate(b-a,Pi/2.0),w=Rotate(c-b,Pi/2.0);
    if(dcmp(Dot(v,w))==0){
        if(dcmp(Len(a-b)+Len(b-c)-Len(a-c))==0) return (a+c)/2;
        if(dcmp(Len(a-c)+Len(c-b)-Len(a-b))==0) return (a+b)/2;
        if(dcmp(Len(b-a)+Len(a-c)-Len(b-c))==0) return (b+c)/2;
    }
    else return GetLineintersection(p,v,q,w);
}
inline void Min_Circular(Point* p,int n){
    random_shuffle(p+1,p+n+1); Point c=p[1]; double r=0;
    for(int i=2;i<=n;++i) if(dcmp(Len(c-p[i])-r)>0){
        c=p[i]; r=0;
        for(int j=1;j<i;++j) if(dcmp(Len(c-p[j])-r)>0){
            c=(p[i]+p[j])/2.0; r=Len(c-p[i]);
            for(int k=1;k<j;++k) if(dcmp(Len(c-p[k])-r)>0){
                c=Get_c(p[i],p[j],p[k]); r=Len(c-p[i]);
            }
        }
    }
    printf("%.2lf %.2lf %.2lf\n",c.x,c.y,r);
}
int main(){
    int n=In();
    for(int i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
    Min_Circular(p,n);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/pkh68/p/10539756.html