POJ3130 How I Mathematician Wonder What You Are! 半平面交判多边形是否有核

来源:互联网 发布:java图书销售管理系统 编辑:程序博客网 时间:2024/04/27 20:58

大家都很强,可与之共勉 。

题意:
  按顺序给您n个点,问您这n个点依次连接的多边形是否有核。
  4n50太小了满足不了我
  多边形的核是平面简单多边形的核是该多边形内部的一个点集,该点集中任意一点与多边形边界上一点的连线都处于这个多边形内部。
  也就是说如果我以这个多边形的每条边当成一个半平面,做半平面交,交出来的图形顶点数大于3即可。

  模板题(我就是来存板子的

# 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 ) ;        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 100010bool HalfPlaneIntersect ( Line* l, int n, Point* p )  {    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 ;    dq [++ top] = dq [bot] ;    int cnt = 0 ;    for ( i = bot ; i < top ; ++ i ) p [cnt ++] = GetIntersect ( l [dq [i]], l [dq [i + 1]] ) ;    return cnt >= 3 ;}Line l [N] ;Point p [N] ;# undef Nint main ( )  {//  freopen ( "in.txt", "r", stdin ) ;    int n ;    while ( ~ scanf ( "%d", & n ) && n )  {        for ( int i = 0 ; i < n ; ++ i )  {            static double x, y ;            scanf ( "%lf%lf", & x, & y ) ;            p [i] = Point ( x, y ) ;        }        for ( int i = 0 ; i < n ; ++ i )  {            l [i] = Line ( p [i], p [i + 1 >= n ? i + 1 - n : i + 1] ) ;        }        puts ( HalfPlaneIntersect ( l, n, p ) ? "1" : "0" ) ;    }   }
阅读全文
0 0