http://acm.pku.edu.cn/JudgeOnline/problem?id=3525
半平面交

#include < iostream >
#include
< deque >
#include
< algorithm >
#include
< cmath >
#include
< complex >
#include
< cstdio >
#include
< vector >
using   namespace  std;

const   double  PI  =  acos(  - 1.0  );
const   double  inf  =   10000.0 ;
const   double  eps  =  1e - 8 ;
typedef complex
< double >  point;

double   operator ^ ( point a, point b ) return imag( conj(a) * b ); }
int  dblcmp(  double  x ) return ( x < -eps )? -1 : x>eps ; }

struct  line
{
    point a, b;
    
double angle;
    line( )
{ }
    line( point u, point v ):a( u ),b( v )
{ angle = arg( b - a ); }
    
bool operator<const line &l ) const 
    
{
        
return dblcmp( angle-l.angle )<0 ||
            dblcmp( angle
-l.angle )==0 && dblcmp( b-a^l.b-a )<0;
    }

}
;
deque
< point >  P;
deque
< int >  E;
vector
< line >  cut;
vector
< point >  pp;

point rotation( point p1, point p2, 
double  r )  //  逆时针旋转90度,长度变为r
{
    point p;
    
double t = r / abs( p2 - p1 );
    p.real( ( imag(p1) 
- imag(p2) ) * t );
    p.imag( ( real(p2) 
- real(p1) ) * t );
    
return p;
}

bool  onLeft( point p, line l ) {    return ( l.b-l.a^p-l.a) >= 0; } // 要有等号
point  operator * ( line l1, line l2 )
{
    
double t = l1.a - l2.a^ l1.b - l2.a;
    
double s = l1.b - l2.b^ l1.a - l2.b;
    
return l2.a + ( l2.b - l2.a ) * t / ( t + s );
}

void  MyUnique( )
{
    vector
<line> tem;
    tem.push_back( cut[
0] );
    
forint i = 1; i < cut.size( ); i++ )
    
{
        
if( dblcmp( tem.back( ).angle - cut[i].angle ) != 0 )
            tem.push_back( cut[i] );
    }

    cut 
= tem;
}

bool  solve( )
{
    sort( cut.begin( ), cut.end( ) );
    MyUnique( );
    point last;
    
bool ok = false
    
forint i = 0; i < cut.size( ); i++ )
    
{
        
int step = dblcmp( cut[i].angle - cut[0].angle -  PI );
        
if( ok && onLeft( last, cut[i] ) )continue;
        
while!P.empty( ) && !onLeft( P.back( ), cut[i] ) ) P.pop_back( ), E.pop_back( );
        
if( step >= 0 )
        
{
            
while!P.empty( ) && !onLeft( P.front( ), cut[i]) ) P.pop_front( ), E.pop_front( );
            
if( P.empty( ) )return false;
        }

        
if!E.empty( ) )P.push_back( cut[ E.back( ) ] * cut[i] );
        E.push_back( i );
        
if( step > 0 )ok = true, last = cut[ E.front( ) ] * cut[ E.back( ) ];
    }

    P.push_back( last );
    
return true;
}


int  main(  int  argc,  char   * argv[] )
{
    
int i,n,t,sz;
    
double x,y,low,high,mid;
    point p;
    
while( scanf("%d"&n) && n )
    
{
        cut.clear( );
        P.clear( );
        E.clear( );
        pp.clear( ); 
        
for( i = 0; i < n; i++ )
        
{
            scanf(
"%lf %lf"&x, &y );
            pp.push_back( point( x, y ) );
            
//cut.push_back( line( point( x1,y1 ), point( x2, y2 ) ) );
        }

        low
=0.0, high = inf;
        
while( dblcmp( low-high ) < 0 )
        
{
            mid 
= ( low + high ) / 2.0;
            cut.clear( );
            P.clear( );
            E.clear( );
            sz
=pp.size( );
            p 
= rotation( pp[sz-1], pp[0], mid );
            cut.push_back( line( pp[sz
-1]+p, pp[0]+p ) );
            
for( i=0; i<sz-1; i++ )
            
{
                p 
= rotation( pp[i], pp[i+1], mid );
                cut.push_back( line( pp[i]
+p, pp[i+1]+p ) );
            }

            
if( solve( ) )
                low 
= mid;
            
else high = mid;
        }

        printf(
"%lf\n",mid);
    }

    
return 0;
}