POJ1228+凸包

见代码。

  1 /*

  2 凸包(稳定凸包)

  3 题意:给出一些点,这些点要么是凸包的顶点要么是边上的。

  4 证明每条边上都至少有3个点。

  5 */

  6 #include<stdio.h>

  7 #include<string.h>

  8 #include<stdlib.h>

  9 #include<algorithm>

 10 #include<iostream>

 11 #include<queue>

 12 #include<map>

 13 #include<stack>

 14 #include<set>

 15 #include<math.h>

 16 using namespace std;

 17 typedef long long int64;

 18 //typedef __int64 int64;

 19 typedef pair<int64,int64> PII;

 20 #define MP(a,b) make_pair((a),(b)) 

 21 const int maxn = 1005;

 22 const int inf = 0x7fffffff;

 23 const double pi=acos(-1.0);

 24 const double eps = 1e-8;

 25 

 26 struct Point {

 27     double x,y;

 28     bool operator < ( const Point p ) const {

 29         return y<p.y||(y==p.y&&x<p.x);

 30     }

 31 }res[ maxn ],pnt[ maxn ];

 32 bool flag[ maxn ][ maxn ];//f[i][j]:点ij之间是否还有点

 33 bool ok[ maxn ];//ok[i]:i是否是凸包的顶点

 34 

 35 double xmult( Point sp,Point ep,Point op ){

 36     return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);

 37 }

 38 

 39 double dis2( Point a,Point b ){

 40     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);

 41 }

 42 

 43 double dis( Point a,Point b ){

 44     return sqrt( dis2(a,b) );

 45 } 

 46 

 47 bool PointOnLine( Point a,Point L,Point R ){

 48     return ( fabs(xmult( a,L,R ))<eps )&&( (a.x-L.x)*(a.x-R.x)<eps )&&( (a.y-L.y)*(a.y-R.y)<eps );

 49 }

 50 

 51 int Garham( int n ){

 52     int top = 1;

 53     sort( pnt,pnt+n );

 54     if( n==0 ) return 0;

 55     else res[ 0 ] = pnt[ 0 ];

 56     if( n==1 ) return 1;

 57     else res[ 1 ] = pnt[ 1 ];

 58     if( n==2 ) return 2;

 59     else res[ 2 ] = pnt[ 2 ];

 60     for( int i=2;i<n;i++ ){

 61         while( top>0&&xmult( res[top],res[top-1],pnt[i] )>=0 )

 62             top--;

 63         res[ ++top ] = pnt[ i ];

 64     }

 65     int tmp = top;

 66     res[ ++top ] = pnt[ n-2 ];

 67     for( int i=n-3;i>=0;i-- ){

 68         while( top!=tmp&&xmult( res[top],res[top-1],pnt[i] )>=0 )

 69             top--;

 70         res[ ++top ] = pnt[ i ];

 71     }

 72     return top;

 73 }

 74 

 75 int main(){

 76     int T;

 77     scanf("%d",&T);

 78     while( T-- ){

 79         int n;

 80         scanf("%d",&n);

 81         for( int i=0;i<n;i++ )

 82             scanf("%lf%lf",&pnt[i].x,&pnt[i].y);

 83         if( n<=5 ){

 84             puts("NO");

 85             continue;

 86         }//至少要6个点

 87         int cnt = Garham( n );

 88         memset( ok,false,sizeof( ok ) );

 89         memset( flag,false,sizeof( flag ) );

 90         for( int i=0;i<n;i++ ){

 91             for( int j=0;j<cnt;j++ ){

 92                 if( pnt[i].x==res[j].x&&pnt[i].y==res[j].y ){

 93                     ok[ i ] = true;

 94                     break;

 95                 }

 96             }

 97         }

 98         for( int i=0;i<n;i++ ){

 99             if( !ok[i] ){

100                 for( int j=0;j<cnt;j++ ){

101                     if( PointOnLine( pnt[i],res[j],res[(j+1)%cnt]) ){

102                         flag[ j ][ (j+1)%cnt ] = true;

103                     }

104                 }

105             }

106         }

107         bool ans = true;

108         for( int i=0;i<cnt;i++ ){

109             if( flag[ i ][ (i+1)%cnt ]==false ){

110                 ans = false;

111                 break;

112             }

113         }

114         if( ans ) printf("YES\n");

115         else puts("NO");

116     }

117     return 0;

118 }
View Code

 

你可能感兴趣的:(poj)