Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1375
For example, there is a light source on ceiling, and there are circular pipes on ceiling and floor. It is required that the area of the light source cannot be found on the last floor.
It is relatively simple. Two tangent lines are directly obtained for each circle, and then the area blocked by the circle (BX, ex) is obtained)
Finally, sort these regions by BX, and then perform a linear scan to obtain the non-Intersecting regions.
PS: The accuracy of this question is very important. In addition, when finding the tangent of the point to the circle, first find the vector of the point and the center, and then rotate the vector clockwise and counterclockwise to obtain the coordinate of the cut point.
# Include < Stdio. h >
# Include < Math. h >
# Include < Algorithm >
Using Namespace STD;
# Define EPS 1.0e-6
# Define Equ (x, y) (FABS (x-y) <EPS)
StructPoint {
DoubleX, Y;
};
Struct Tnode {
Double BX, ex;
};
Inline Bool Operator < ( Const Tnode & T1, Const Tnode & T2 ){
Return T1.bx < T2.bx | (Equ (t1.bx, t2.bx) && T1.ex < T2.ex );
}
Tnode ans [500];
InlineVoidSwap (Double &X,Double &Y ){
DoubleT=X;
X=Y;
Y=T;
}
// Rotate angle of vector p counterclockwise
Point rotate (point P, Double Angle ){
Point res;
Res. x = P.x * Cos (angle) - P. Y * Sin (angle );
Res. Y = P.x * Sin (angle) + P. Y * Cos (angle );
Return Res;
}
// Calculate the result1 and result2 of the poi circle (O, R ).
Void Tangentpoint_pc (point poi, point O, Double R, Point & Result1, Point & Result2 ){
Double Line = SQRT (POI. x - O. X) * (POI. x - O. X) + (POI. Y - O. Y) * (POI. Y - O. Y ));
Double Angle = ACOs (R / Line );
Point unitvector, Lin;
Lin. x = Poi. x - O. X;
Lin. Y = Poi. Y - O. Y;
Unitvector. x = Lin. x / SQRT (Lin. x * Lin. x + Lin. Y * Lin. Y) * R;
Unitvector. Y = Lin. Y / SQRT (Lin. x * Lin. x + Lin. Y * Lin. Y) * R;
Result1 = Rotate (unitvector, - Angle );
Result2 = Rotate (unitvector, angle );
Result1.x + = O. X;
Result1.y + = O. Y;
Result2.x + = O. X;
Result2.y + = O. Y;
Return ;
}
Int Main (){
Point bp;
Point op;
Double R;
Int N;
While (Scanf ( " % D " , & N) ! = EOF ){
If (N = 0 ) Continue ;
Scanf ( " % Lf " , & BP. X, & BP. y );
For ( Int I = 0 ; I < N; I ++ ){
Scanf ( " % Lf " , & Op. X, & Op. y, & R );
Point R1, R2;
Tangentpoint_pc (BP, op, R, R1, R2 );
Double X1 = (R1.y * BP. x - R1.x * BP. Y) / (R1.y - BP. y );
Double X2 = (R2.y * BP. x - R2.x * BP. Y) / (R2.y - BP. y );
If (X1 > X2) Swap (x1, x2 );
Ans [I]. bx = X1;
Ans [I]. Ex = X2;
}
Sort (ANS, ANS + N );
Printf ( " %. 2lf " , ANS [ 0 ]. Bx );
Double Prevy = Ans [ 0 ]. Ex;
For ( Int I = 1 ; I < N; I ++ ){
If ( ! Equ (prevy, ANS [I]. bx) && Ans [I]. bx > Prevy ){
Printf ( " %. 2lf \ n %. 2lf " , Prevy, ANS [I]. bx );
}
If (Prevy < Ans [I]. Ex) prevy = Ans [I]. Ex;
}
Printf ( " %. 2lf \ n " , Prevy );
Putchar ( ' \ N ' );
}
Return 0;
}