poj 1584 A Round Peg in a Ground Hole

这个题首先判断是否是凸多边形,再判断圆心是否在凸多边形内,再判断凸多边形是否在圆内;

做法用Graham判断是否是多边形;

再把圆心加入到多边形的点之中,再用Graham看圆心是否在凸多边形上,如果在就代表圆心在凸多边形外;

再用点到直线的距离,fabs(A*x + B*y + c)/sqrt(A*A + B*B);

极角排序法:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
using namespace std;
class Point
{
public:
      double x,y;    
}point[200],point1[200];
double multi( Point p1, Point p2 , Point q )
{
    return ( p1.x - q.x )*( p2.y - q.y ) - ( p2.x - q.x )*( p1.y - q.y );    
}
double Distance( Point a , Point b )
{
   return sqrt(( a.x - b.x )*( a.x - b.x ) + ( a.y - b.y )*( a.y - b.y ));    
}
int dcmp( double x )
{
   if( fabs( x ) < 1.0e-8 ) return 0;
   if( x < 0 ) return -1;
   return 1;
}
bool cmp( Point a , Point b )
{
   double t = multi( a , b , point[1] );
   if( t > 0 ) return true;
   if( fabs( t ) < 1.0e-8 )
      if( dcmp( b.x - point[1].x ) >0 && Distance( a, point[1] ) < Distance( b , point[1] ))
       return true;
   return false;     
}
bool Graham( int n ,int opt)
{
     int len = 0;
     Point p[124];
     for( int i = 1; i <= n ; i ++ )
     {
        while( len >=2 && dcmp(multi( p[len-1] , point[i] ,p[len-2] )) < 0 )
               len --;
        p[len++] = point[i];
     }        
     if( opt == 1 )
     {
         if( len == n ) return true;
         else return false;        
     }
     else
     {
         for( int i = 0; i < len ; i++ )
         {
             if( dcmp(p[i].x - point[0].x) ==0 && dcmp(p[i].y - point[0].y)==0 )
                 return false;        
         }
         return true;
     }
}
double Dis( double A ,double B , Point p ,Point q)
{
   return  fabs( A*( q.y - p.y ) - B*( q.x - p.x )) /sqrt(( A*A + B*B ) );
}
bool Solve( int n ,double R )
{
    point1[n+1] = point1[1];
    for( int i = 1; i <= n ; i ++ )
    {
       double A = point1[i + 1].x - point1[i].x;
       double B = point1[i + 1].y - point1[i].y;
       double d = Dis( A ,B,point1[i],point1[0] );// printf( "%lf\n",d );
       if(  dcmp(d- R) < 0 ) 
            return false;     
    }
    return true;
}
int main(  )
{
    int n;
    double R;
    while( scanf( "%d",&n ), n>=3 )
    {
        scanf( "%lf %lf %lf",&R,&point[0].x, &point[0].y );
       for( int i =1 ; i <= n ; i++ )
       {
          scanf( "%lf %lf",&point[i].x ,&point[i].y );
          if( point[i].y <= point[1].y )
          {
              if( point[i].y < point[1].y ) swap( point[1],point[i] );
              else if(fabs(point[i].y - point[1].y)<1.0e-8&&point[i].x < point[1].x)
                  swap( point[i] ,point[1] );        
          }        
       }
       sort( point + 2 ,point + n + 1 , cmp );
       if( Graham( n , 1 ) == false) printf( "HOLE IS ILL-FORMED\n" );
       else
       {
           if( dcmp(point[0].y - point[1].y) < 0 ) printf( "PEG WILL NOT FIT\n" );
           else if( dcmp(point[0].y - point[1].y)==0 && dcmp(point[0].x - point[1].x)<=0)
                printf( "PEG WILL NOT FIT\n" );
                else 
                {
                    point[n+1] = point[0];
                    for( int i = 0 ; i <= n   ; i ++ )
                         point1[i] = point[i];            
                    sort( point + 2 , point + n + 2 , cmp );  
                    if( Graham( n + 1 , 2 )==false ) printf( "PEG WILL NOT FIT\n" );
                    else if( Solve( n ,R  ) ) printf( "PEG WILL FIT\n" );
                    else printf( "PEG WILL NOT FIT\n" );    
                }    
       }
       
    }
    //system( "pause" );
    return 0;
}

 水平排序法:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
using namespace std;
class Point
{
public:
      double x,y;    
}point[200],point1[200],p[200];
int len;
double multi( Point p1, Point p2 , Point q )
{
    return ( p1.x - q.x )*( p2.y - q.y ) - ( p2.x - q.x )*( p1.y - q.y );    
}
int dcmp( double x )
{
   if( fabs( x ) < 1.0e-8 ) return 0;
   if( x < 0 ) return -1;
   return 1;
}
bool cmp( Point a , Point b )
{
   if( dcmp( a.y - b.y )==0 )
       return a.x < b.x;
   return a.y < b.y;    
}
bool Graham( int n ,int opt)
{
     len = 0;
     for( int i = 1; i <= n ; i ++ )
     {
        while( len >=2 && dcmp(multi( p[len-1] , point[i] ,p[len-2] )) < 0 )
               len --;
        p[len++] = point[i];
     }
     int t = len + 1;
     for( int i = n -1 ; i >= 1; i -- )    
     {
         while( len >= t && dcmp(multi( p[len-1] , point[i] ,p[len-2] )) < 0 )
                len -- ;
        p[len++] = point[i];
     }    
     if( opt == 1 )
     {
         if( len == n +  1 ) return true;
         else return false;        
     }
     else
     {
         for( int i = 0; i < len ; i++ )
         {
             if( dcmp(p[i].x - point[0].x) ==0 && dcmp(p[i].y - point[0].y)==0 )
                 return false;        
         }
         return true;
     }
}
double Dis( double A ,double B , Point p ,Point q)
{
   return  fabs( A*( q.y - p.y ) - B*( q.x - p.x )) /sqrt(( A*A + B*B ) );
}
bool Solve( double R )
{ 
    for( int i = 0; i < len -1 ; i ++ )
    {
       double A = p[i + 1].x - p[i].x;
       double B = p[i + 1].y - p[i].y;
       double d = Dis( A ,B,p[i],point[0] );// printf( "%lf\n",d );
       if(  dcmp(d- R) < 0 ) 
            return false;     
    }
    return true;
}
int main(  )
{
    int n;
    double R;
    while( scanf( "%d",&n ), n>=3 )
    {
        scanf( "%lf %lf %lf",&R,&point[0].x, &point[0].y );
       for( int i =1 ; i <= n ; i++ )
       {
          scanf( "%lf %lf",&point[i].x ,&point[i].y );        
       }
       sort( point + 1 ,point + n + 1 , cmp );
       if( Graham( n , 1 ) == false) printf( "HOLE IS ILL-FORMED\n" );
       else
       {    point[n+1] = point[0];        
            sort( point + 1 , point + n + 2 , cmp );  
            if( Graham( n + 1 , 2 )==false ) printf( "PEG WILL NOT FIT\n" );
            else if( Solve( R  ) ) printf( "PEG WILL FIT\n" );
            else printf( "PEG WILL NOT FIT\n" );        
       }
       
    }
    //system( "pause" );
    return 0;
}

 

 

测试数据

Sample Input

5 1.5 1.5 2.0

1.0 1.0

2.0 2.0

1.75 2.0

1.0 3.0

0.0 2.0

5 1.5 1.5 2.0

1.0 1.0

2.0 2.0

1.75 2.5

1.0 3.0

0.0 2.0

3  0.1  0.2 0.0

-0.5 1.0

0.5 -1.0

0.5 1.0

3  0.25  0.2 0.0

-0.5 1.0

0.5 -1.0

0.5 1.0

3 0.1 1.6 1.2

1.0 1.0

2.0 1.0

1.0 2.0

6 0.1 1.6 1.2

1.0 1.0

1.5 1.0

2.0 1.0

1.2 1.8

1.0 2.0

1.0 1.5

3 0.1 2.0 2.0

1.0 1.0

2.0 1.0

1.0 2.0

4  1.0  2.0 1.0

0.0 0.0

0.0 4.0

4.0 4.0

4.0 0.0

4  1.0  3.5 1.0

0.0 0.0

0.0 4.0

4.0 4.0

4.0 0.0

4  0.2  1.5 1.0

1.0 1.0

2.0 2.0

1.0 3.0

0.0 2.0

4  0.4  1.5 1.0

1.0 1.0

2.0 2.0

1.0 3.0

0.0 2.0

5  0.2  1.5 2.5

1.0 1.0

2.0 2.0

1.75 2.75

1.0 3.0

0.0 2.0

5  0.2  1.5 2.5

1.0 1.0

2.0 2.0

1.75 2.5

1.0 3.0

0.0 2.0

9 0.2 0.5 2.5

0.0 0.0

1.0 0.0

1.0 1.0

2.0 1.0

2.0 0.0

3.0 0.0

3.0 5.0

1.5 5.0

0.0 5.0

9 0.2 0.5 2.5

0.0 0.0

1.0 0.0

1.0 -1.0

2.0 -1.0

2.0 0.0

3.0 0.0

3.0 5.0

1.5 5.0

0.0 5.0

7 0.2 0.5 2.5

0.0 0.0

1.0 0.0

2.0 0.0

3.0 0.0

3.0 5.0

1.5 5.0

0.0 5.0

4 0.1 1 0.5

0 2

1 0

2 2

1 1

1

Sample Output

HOLE IS ILL-FORMED

PEG WILL NOT FIT

PEG WILL FIT

PEG WILL NOT FIT

PEG WILL FIT

PEG WILL FIT

PEG WILL NOT FIT

PEG WILL FIT

PEG WILL NOT FIT

PEG WILL NOT FIT

PEG WILL NOT FIT

PEG WILL FIT

PEG WILL NOT FIT

HOLE IS ILL-FORMED

HOLE IS ILL-FORMED

PEG WILL FIT

HOLE IS ILL-FORMED

posted @ 2012-07-11 09:14  wutaoKeen  阅读(190)  评论(0编辑  收藏  举报