ブログのリンク
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)。 }