大家都很强, 可与之共勉 。
题意:
依次给您
n
个点,顺次围成一只多边形,问您这个多边形内的点到边界的距离最远是多少?
其中
题解:
二分答案,然后将每个半平面缩进答案那么多,判是否交集为空。
辣叽POJ,读入用%lf,输出用%f,mmp
# include <cmath>
# include <cstdio>
# include <algorithm>
template < class T > inline T min ( T a, T b ) { return a > b ? b : a ; }
template < class T > inline T max ( T a, T b ) { return a > b ? a : b ; }
const double eps = 1e-8 ;
const double Pi = acos ( -1 ) ;
inline int epssgn ( double x ) {
return ( x > - eps ) - ( x < eps ) ;
} // x > eps -> 1 ; x < -eps -> -1 ; x == 0 -> 0 ;
struct Vector {
double x, y ; // len ;
Vector ( ) { }
Vector ( double x, double y ) : x ( x ), y ( y ) { /*len = sqrt ( x * x + y * y ) ;*/ }
inline Vector operator + ( const Vector rhs ) const {
return Vector ( x + rhs.x, y + rhs.y ) ;
}
inline Vector operator - ( const Vector rhs ) const {
return Vector ( x - rhs.x, y - rhs.y ) ;
}
inline Vector operator * ( const double k ) const {
return Vector ( x * k, y * k ) ;
}
inline Vector operator / ( const double k ) const {
return Vector ( x / k, y / k ) ;
}
inline double operator * ( const Vector rhs ) const {
return x * rhs.x + y * rhs.y ;
} // µã»ý
inline double operator % ( const Vector rhs ) const {
return x * rhs.y - y * rhs.x ;
} //²æ»ý
} ;
struct Point {
double x, y ;
Point ( ) { }
Point ( double x, double y ) : x ( x ), y ( y ) { }
inline Vector operator - ( const Point rhs ) const {
return Vector ( x - rhs.x, y - rhs.y ) ;
}
} ;
struct Line {
double a, b, c, angle ;
Point p1, p2 ;
Line ( ) { }
Line ( Point s, Point e ) : p1 ( s ), p2 ( e ) {
a = s.y - e.y ;
b = e.x - s.x ;
c = e.y * s.x - e.x * s.y ;
angle = atan2 ( e.y - s.y, e.x - s.x ) ; // !!!
}
inline bool operator < ( const Line& rhs ) const {
return angle < rhs.angle ;
}
} ; // ax + by + c = 0 ;
inline bool Parallel ( Line l1, Line l2 ) {
return epssgn ( l1.a * l2.b - l1.b * l2.a ) == 0 ;
}
inline bool LineEqual ( Line l1, Line l2 ) {
if ( ! Parallel ( l1, l2 ) ) return 0 ;
return ( epssgn ( l1.b * l2.a - l2.b * l1.a ) == 0 ) && ( epssgn ( l1.c * l2.a - l2.c * l1.a ) == 0 ) ;
}
inline Point GetIntersect ( Line l1, Line l2 ) {
return Point ( ( l1.b * l2.c - l2.b * l1.c ) / ( l1.a * l2.b - l2.a * l1.b ), ( l2.a * l1.c - l1.a * l2.c ) / ( l1.a * l2.b - l2.a * l1.b ) ) ;
}
struct Lcmp {
inline bool operator ( ) ( const Line& l1, const Line& l2 ) {
int d = epssgn ( l1.angle - l2.angle ) ;
if ( ! d ) return ( bool ) ( epssgn ( ( l2.p1 - l1.p1 ) % ( l2.p2 - l1.p1 ) ) > 0 ) ; // No >=
return d < 0 ;
}
} ;
inline bool IntersectionOutOfHalfPlane ( Line& hpl, Line& l1, Line& l2 ) {
Point p = GetIntersect ( l1, l2 ) ;
return ( epssgn ( ( hpl.p1 - p ) % ( hpl.p2 - p ) ) < 0 ) ; // intersection is on left ;
}
# define N 100010
int HalfPlaneIntersect ( Line* l, int n ) {
static int dq [N] ;
int top, bot ;
std :: sort ( l, l + n, Lcmp ( ) ) ;
int i, j ;
for ( i = j = 0 ; i < n ; ++ i )
if ( epssgn ( l [i].angle - l [j].angle ) > 0 ) {
l [++ j] = l [i] ;
}
n = j + 1 ;
dq [bot = 0] = 0 ;
dq [top = 1] = 1 ;
for ( i = 2 ; i < n ; ++ i ) {
while ( top > bot && IntersectionOutOfHalfPlane ( l [i], l [dq [top]],l [dq [top - 1]] ) ) -- top ;
while ( top > bot && IntersectionOutOfHalfPlane ( l [i], l [dq [bot]],l [dq [bot + 1]] ) ) ++ bot ;
dq [++ top] = i ;
}
while ( top > bot && IntersectionOutOfHalfPlane ( l [dq [bot]], l [dq [top]],l [dq [top - 1]] ) ) -- top ;
while ( top > bot && IntersectionOutOfHalfPlane ( l [dq [top]], l [dq [bot]],l [dq [bot + 1]] ) ) ++ bot ;
return top - bot + 1 ;
}
inline double len ( const Vector& p ) {
return sqrt ( p.x * p.x + p.y * p.y ) ;
}
inline Line HalfPlaneMoveIn ( const Line &hpl, const double &dis ) {
double dx = hpl.p1.x - hpl.p2.x ;
double dy = hpl.p1.y - hpl.p2.y ;
double ll = len ( hpl.p1 - hpl.p2 ) ;
Point pa = Point ( dis * dy / ll + hpl.p1.x, hpl.p1.y - dis * dx / ll ) ;
Point pb = Point ( dis * dy / ll + hpl.p2.x, hpl.p2.y - dis * dx / ll ) ;
return Line ( pa, pb ) ;
}
Line l [N] ;
Point p [N] ;
Line lines [N] ;
int n ;
inline bool chk ( double mid ) {
for ( int i = 0 ; i < n ; ++ i ) lines [i] = HalfPlaneMoveIn ( l [i], mid ) ;
return HalfPlaneIntersect ( lines, n ) >= 3 ;
}
# undef N
int main ( ) {
while ( ~ scanf ( "%d", & n ) && n ) {
for ( int i = 0 ; i < n ; ++ i ) scanf ( "%lf%lf", & p [i].x, & p [i].y ) ;
for ( int i = 0 ; i < n ; ++ i ) {
l [i] = Line ( p [i], p [i + 1 >= n ? i + 1 - n : i + 1] ) ;
}
double l = 0, r = 1e5, ans ;
while ( r - l >= eps ) {
double mid = ( l + r ) / 2 ;
chk ( mid ) ? l = ans = mid : r = mid ;
}
printf ( "%.7f\n", ans ) ;
}
}