Poj_1113
We can first convert the problem: first obtain the convex hull of each point in the castle, and then find the perimeter of the closed graph with the distance from the convex hull being L.
As to why it is converted into a convex hull first, we may use the reverse verification method. If the wall is extended to the internal direction of the convex hull, it will inevitably be extended, which will be more expensive.
The shape of a wall is not hard to imagine. One part is parallel to the side and equal to the side length of each side, and the other part is the arc shape of the corner, in addition, the arc center angle is the angle of the direction vector of the two sides.
When calculating the perimeter, one part is the circumference of the convex hull, and the other part is the sum of the arc lengths. Of course, we can find the arc on each corner and accumulate them together, but this will involve a lot of operations on trigonometric functions and open functions, and there will be more loss of precision, as a matter of fact, we will find that the arc is a complete circle. Therefore, After calculating the circumference of the convex hull, we can add a circle with a radius of L.
# Include <stdio. h>
# Include < String . H>
# Include <stdlib. h>
# Include <math. h>
# Define Maxd 1010
Struct Point
{
Int X, Y;
} P [maxd], Res [maxd];
Int N, L, P;
Int CMP ( Const Void * _ P, Const Void * _ Q)
{
Point * P = (point *) _ p, * q = (point *) _ q;
If (P-> Y = Q-> Y)
Return P-> X-Q-> X;
Return P-> Y-Q-> Y;
}
Int Det ( Int X1, Int Y1, Int X2, Int Y2)
{
Return X1 * Y2-X2 * Y1;
}
Void Init ()
{
Int I, J, K;
For (I = 0 ; I <n; I ++)
Scanf ( " % D " , & P [I]. X, & P [I]. y );
Qsort (p, n, Sizeof (P [ 0 ]), CMP );
}
Int Del ( Int Top,Int I)
{
If (Det (RES [Top]. X-res [Top- 1 ]. X, Res [Top]. Y-res [Top- 1 ]. Y, P [I]. X-res [Top]. X, P [I]. Y-res [Top]. Y) < 0 )
Return 1 ;
Return 0 ;
}
Int Graham ()
{
Int I, J, K, Top = 1 , Mint;
Res [ 0 ] = P [ 0 ], Res [ 1 ] = P [ 1 ];
For (I = 2 ; I <n; I ++)
{
While (Top & del (top, I ))
-- Top;
Res [++ top] = P [I];
}
Mint = top;
Res [++ top] = P [n- 2 ];
For (I = N- 3 ; I> = 0 ; I --)
{
While (Top! = Mint & del (top, I ))
-- Top;
Res [++ top] = P [I];
}
Return Top;
}
Double Sqr ( Double X)
{
Return X * X;
}
Double Calculate ()
{
Int I, J, K;
Double Ans = 0 ;
Res [p + 1 ] = Res [ 1 ];
For (I = 0 ; I <p; I ++)
Ans + = SQRT (sqr (RES [I]. X-res [I + 1 ]. X) + sqr (RES [I]. Y-res [I + 1 ]. Y ));
Return Ans + 2 * ACOs (- 1.0 ) * L;
}
Void Solve ()
{
Int I, J, K;
Double Ans;
P = Graham ();
Ans = calculate ();
Printf (" %. 0lf \ n " , ANS );
}
Int Main ()
{
While (Scanf ( " % D " , & N, & L) = 2 )
{
Init ();
Solve ();
}
Return 0 ;
}