Poj_1375
For this question, we can first use the analytic ry method to find the two tangent of each circle and obtain the shadow part. Then, we can combine the shadow part.
During shadow merging, you can sort the values by left endpoint for processing convenience. You can enumerate each interval from the back to the front and start searching forward from this interval, if there is an intersection between the previous interval and this interval, delete this interval and update the range of the previous interval into the union of the two intervals. This is O (n ^ 2) complexity.
A better way is to first assign the left endpoint of the first interval to X, the right endpoint to Y, and then scan the interval backward, if the left endpoint of the current range is greater than Y, the records X and Y are output, and X and Y are updated to the left and right endpoints of the current range, if the left endpoint of the current range is not larger than Y, then Y is updated to the right endpoint of the current range and Y to a greater margin. Finally, X and Y are output, this is the complexity of O (N) (it only refers to the complexity of merging intervals, and the complexity of sorting previously facing intervals is O (nlogn )).
# Include <stdio. h>
# Include < String . H>
# Include <stdlib. h>
# Include <math. h>
# Define Zero 1e-8
# Define Maxd 510
Int N, R [maxd];
Double BX, by, CX [maxd], CY [maxd], Cr [maxd], LX [maxd], RX [maxd];
Int CMP ( Const Void * _ P, Const Void * _ Q)
{
Int * P = ( Int *) _ P;
Int * Q = ( Int *) _ Q;
Return Lx [* p] <lx [* q]? - 1 : 1 ;
}
Double Max ( Double X, Double Y)
{
Return X> Y? X: Y;
}
Int DCMP (Double X)
{
If (FABS (x) <zero)
Return 0 ;
If (X < 0 )
Return - 1 ;
Return 1 ;
}
Void Init ()
{
Int I, J, K;
Scanf ( " % Lf " , & BX, & );
For (I = 0 ; I <n; I ++)
Scanf ( " % Lf " , & CX [I], & CY [I], & cr [I]);
}
Void Solve ()
{
Int I, J;
Double K1, K2, A1, A2, A3, X, Y;
For (I = 0 ; I <n; I ++)
{
A1 = (CX [I]-bx) * (CX [I]-bx)-Cr [I] * Cr [I];
A2 = 2 * (By-cy [I]) * (CX [I]-bx );
A3 = (CY [I]-by) * (CY [I]-by)-Cr [I] * Cr [I];
If (DCMP (A1) = 0 )
{
K1 = (-A3)/A2;
If (K1 < 0 )
Lx [I] = Bx, RX [I] = (-by)/k1 + bx;
Else
Lx [I] = (-by)/k1 + bx, RX [I] = Bx;
}
Else
{
K1 = (-A2-SQRT (A2 * A2- 4 * A1 * A3 ))/( 2 * A1 );
K2 = (-A2 + SQRT (A2 * A2- 4 * A1 * A3 ))/(2 * A1 );
Lx [I] = (-by)/k1 + bx, RX [I] = (-by)/k2 + bx;
}
}
For (I = 0 ; I <n; I ++)
R [I] = I;
Qsort (R, n, Sizeof (R [ 0 ]), CMP );
X = Lx [R [ 0 ], Y = RX [R [ 0 ];
For (I =1 ; I <n; I ++)
{
If (DCMP (LX [R [I]-y)> 0 )
{
Printf ( " %. 2lf %. 2lf \ n " , X, y );
X = Lx [R [I], y = RX [R [I];
}
Else
Y = max (Y, RX [R [I]);
}
Printf ( " %. 2lf %. 2lf \ n " , X, y );
}
Int Main ()
{
For (;;)
{
Scanf ( " % D " , & N );
If (! N)
Break ;
Init ();
Solve ();
Printf (" \ N " );
}
Return 0 ;
}