[テンプレート] --bzoj1336をカバーする最小の円

ブログのリンク

https://blog.csdn.net/commonc/article/details/52291822

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
#define N 100005 
typedefをダブルデシベル。
CONST DB EPS = 1E- 10 CONST dBのPI = ACOS( - 1 )。
INT 符号(デシベルK){
     場合(K> EPS)リターン 1それ以外の 場合(K <-eps)のリターン - 1リターン 0 ; 
} 
INT CMP(DB K1、K2 DB){ 戻り記号(k1- K2);}
 int型 inmid(DB K1、K2 DB、DB K3){ リターンサイン(K1〜K3)*記号(K2、K3)<= 0 ;} // K3在[K1、K2]内
の構造体の点{ 
    DB X、Y。演算子 +(constのポイント&K1)のconst { リターン(点){k1.x + X、k1.y + Y};} 演算子 - (CONSTポイント&K1)のconst { リターン(点){X-k1.x、Y - k1.y};} 演算子 *(DB K1)のconst { リターン(点){X * K1、Y * K1};} 
    ポイントオペレータ /(DB K1)のconst {リターン(点){X / K1、Y / K1};}
     int型の 演算子 ==(constのポイント&K1)のconst { 戻り CMP(X、k1.x)== 0 && CMP(Y、k1.y)== 0 。 }
     // 逆时针旋转 
    点ターン(DB K1){ リターン(点){X * COS(K1)-Y * SIN(K1)、X * SIN(K1)+ Y * COS(K1)};} 
    ポイントturn90 (){ リターン(点){ - X、Y};}
     ブール 演算子 <(CONST点K1)のconst {
         INT A = CMP(X、k1.x)。
        もし(== - 1リターン 1 ; それ以外の 場合(== 1の戻り 0 ;  戻り CMP(Y、k1.y)== - 1 
    } 
    DB ABS(){ 戻り SQRT(X * X + Y * Y);} 
    DB ABS2(){ リターン X * X + Y * Y;} 
    DB DIS(点K1){ リターン((* ) - K1) .ABS();} 
    W小数点ユニット(){DB = ABS()。リターン(点){X / W、Y / W};}
     ボイドスキャン(){ ダブル K1、K2。scanf関数(" %LF%LF "、&​​K1、K2&); X = K1。Y = K2;}
     ボイドプリント(){のprintf(" %.11lf%.11lf \ n " 、X、Y);} 
    DB getw(){ 戻りATAN2(Y、X);} 
    ポイントgetdel(){ 場合(記号(X)== - 1 ||(記号(X)== 0 &&記号(Y)== - 1))リターン(* )*( - 1)。他の リターン(* );}
     int型 GETP()のconst { 戻り記号(Y)== 1 ||(符号(Y)== 0 &&記号(X)> = 0 );} 
};
INT inmid(点K1、点K2、点K3){ 戻り inmid(k1.x、k2.x、k3.x)&& inmid(k1.y、k2.y、k3.y);} 
クロスDB(点K1 、点K2){ リターン k1.x * k2.y-k1.y * k2.x;} 
DBドット(点K1、点K2){ リターン k1.x * k2.x + k1.y * k2.y。 } 
 
構造体の円{ 
    点O。デシベルのR; 
    ボイドスキャン(){()o.scan。scanf関数(" %のLF "、&R);}
     int型の内部(点K){ // -1:圆外、0边上、1:圆内
        戻りCMP(R、o.dis(K))。
    } 
}。

int型のn; 
点p [N]。
今の円;
円getcircle(点K1、点K2、点K3){ // 通过三点求元 
    DB A1 = k2.x-k1.x、B1 = k2.y-k1.y、C1 =(A1 * A1 + B1 * B1)/ 2 
    DB A2 = k3.x-k1.x、B2 = k3.y-k1.y、C2 =(A2 * A2 + B2 * B2)/ 2 
    デシベルD = A1 * B2-A2 * B1。
    O点 =(点){k1.x +(C1 * B2-C2 * B1)/d,k1.y+(A1 * C2-A2 * C1)/ D}。
    リターン(円){O、k1.dis(O)}; 
} 


int型のmain(){ 
    CIN >> N。
    以下のためにINT iが= 1 ; I <= N; I ++ 
        のscanf(" %LF%LF "、&​​P [i]は.X、&P [i]の.Y)。
    random_shuffle(P + 1、P + 1 + N-); 
    
    now.r = 0 ; 
    now.o = P [ 1 ];
     のためのINT I = 2 ; I <= N; I ++)IF(now.inside(P [I ])< 0){ // 点p [i]の新規の円形の縁に固定されている 
        now.o = P [i]は、now.r = 0 ;
         のためのINT J = 1。 ; J <I、J ++)IF( now.inside(P [J])< 0){ // 点P [j]は新規の円形の縁に固定されて 
            now.o =(P [I] + P [J])* 0.5 
            now.r= now.o.dis(P [I])。
            int型 K = 1 K ++; K <J)であれば(now.inside(P [K])< 0){ // 三点求圆 
                今= getcircle(P [I]、P [J]、P [ K])。
            } 
        } 
    } 
    のprintf(" %.10lf \ n%.10lf%.10lf \ n " 、now.r、now.ox、now.oy)。
}

 

おすすめ

転載: www.cnblogs.com/zsben991126/p/12358375.html