poj 2074 Line of Sight

这个题就是求无论你站在家的那个地方都能看到财产的最大值;

这个题可以从正面做,直接用叉积求出最大值;

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
class Line
{
public:
      double x1,x2,y;    
}line[10000];
Line house,pro;
int dcmp( double x )
{
   if( fabs( x ) < 1.0e-12 ) return 0;
   if( x < 0 ) return -1;
   return 1;    
}
bool cmp( Line a, Line b )
{
   if( a.x1 < b.x1 ) return true;
   else if( dcmp( a.x1 - b.x1)==0 && a.y < b.y ) return true;
   return false;    
}
double multi( double x1,double y1 ,double x2 ,double y2 )
{
   return x1*y2 - x2*y1;    
}
double segment( double x1,double y1 ,double x2,double y2, Line L )
{
       int d1 = dcmp(multi( x1 - L.x1 , y1 - L.y  ,x2 -L.x1 ,y2 - L.y ));
       int d2 = dcmp(multi( x1 - L.x2 , y1 - L.y  ,x2 -L.x2 ,y2 - L.y ));
       return d1*d2;
}
int view_right( int t ,int n)
{
    for( int i = 0 ; i < n  ; i ++)
    {
       if( segment(house.x1 ,house.y , line[t].x2,line[t].y,line[i] ) < 0 )
           return i;    
    }
    return t;    
}
int view_left( int t ,int n )
{
    for( int i = 0 ; i < n  ; i ++)
    {
       if( segment(house.x2 ,house.y , line[t].x1,line[t].y,line[i] )< 0 )
           return i;    
    }
    return t;    
}
double Max( double a , double b)
{
   return a > b ? a : b;    
}
double Solve( int n )
{
   double ans = 0,A1,B1,A2,B2;
   int t = view_left(  0 , n ),tt=0;
   while( t != tt ) 
   { // printf( "%d\n",t );
  //   getchar();    
        tt = t;
        t = view_left( t , n );
   }
   A1 = house.x2 - line[t].x1;B1 = house.y - line[t].y;
   
   ans = Max( ans , ( pro.y - house.y )*A1/B1 + house.x2 - pro.x1 );
   tt = t = n-1;
   t = view_right( t , n );
   while( t != tt )
   {
        tt = t;
        t = view_right(  t , n );        
   }
   A1 = house.x1 - line[t].x2;B1 = house.y - line[t].y;
   ans = Max( ans ,  pro.x2 - ( ( pro.y - house.y )*A1/B1 + house.x1 ) );
   int i = 0;
   while( i < n )
   {
       tt = t = i;
       t = view_right(  t , n );
       while( tt != t )
       {
          tt = t;
          t = view_right(  t , n );
       }
       A1 = house.x1 - line[t].x2;B1 = house.y - line[t].y;
       int j = 0;
       while( line[j].x1 < line[t].x2 && j < n ) j++;
       if( j == n ) break;
       tt = t = j;
       t = view_left(  t , n );
       while( tt!=t )
       {
          tt = t;
          t = view_left(  t , n );    
       }
      A2 = house.x2 - line[t].x1;B2 = house.y - line[t].y;
      double x1 = ( pro.y - house.y )*A1/B1 + house.x1;
      double x2 = ( pro.y - house.y )*A2/B2 + house.x2 ;
      ans = Max( ans , x2 - x1 );
      i = t;
        
   }
   return ans;    
}
int main(  )
{
    while( scanf( "%lf %lf %lf",&house.x1,&house.x2,&house.y )==3)
    {
        int n,flag = 0,cnt=0;
           if(dcmp(house.x1)==0&&dcmp(house.x2)==0&&dcmp(house.y)==0 ) break;
           scanf( "%lf %lf %lf",&pro.x1, &pro.x2,&pro.y );
           scanf( "%d",&n );
           for( int i = 0; i < n ; i++ )
           {
            scanf( "%lf %lf %lf",&line[i].x1,&line[i].x2,&line[i].y );
            if( dcmp(line[i].y - house.y) ==0 )
            {
               if( dcmp( line[i].x1 - house.x2 ) <= 0 && dcmp( line[i].x2 - house.x1 ) >= 0 )
                    flag = 1;    
            }
            else if( line[i].y < house.y && line[i].y > pro.y )line[cnt++] = line[i];        
        }
        if( flag ) printf( "No View\n" );
        else
        {
            if( cnt == 0 ) printf( "%.2f\n",pro.x2-pro.x1 );
            else
            {  
                sort( line , line + cnt , cmp );
                double view = Solve( cnt );
                if( dcmp( view )==0 ) printf( "No View\n" );
                else printf( "%.2f\n",view ); 
            }
        }
    }
    //system( "pause" );
    return 0;
}

从反面,就是求出他看不到的地方,再线性遍历求出最大值;

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
class Line
{
public:
      double x1,x2,y;    
}line[224];
Line house,pro;
int dcmp( double x )
{
   if( fabs( x ) < 1.0e-12 ) return 0;
   if( x < 0 ) return -1;
   return 1;    
}
bool cmp( Line a, Line b )
{
   if( a.x1 < b.x1 ) return true;
   else if( dcmp( a.x1 - b.x1)==0 && a.y < b.y ) return true;
   return false;    
}
double Max( double a , double b)
{
   return a > b ? a : b;    
}
double Solve( int n )
{
   Line L[224]={0};
   double A1,B,A2;
   for( int i = 0 ; i < n ; i ++ )
   {
      A1 = house.x2 - line[i].x1; 
      B = house.y - line[i].y;
      A2 = house.x1 - line[i].x2;
      L[i].x1 = ( pro.y - house.y )*A1/B + house.x2;
      L[i].x2 = ( pro.y - house.y )*A2/B + house.x1;    
   }
   sort( L , L + n , cmp );
   double ans = 0; 
   if( L[0].x1 > pro.x1 ) ans = L[0].x1 - pro.x1;
   double t = L[0].x2;
   for( int i = 1 ; i < n ; i ++ )
   {
       if( L[i].x1 <= t ) t = Max( t , L[i].x2 );
       else 
       {
            ans = Max( ans , L[i].x1 - t );    
            t = L[i].x2;
       }    
   }
   ans = Max( ans , pro.x2 - t );
   return ans;    
}
int main(  )
{
    while( scanf( "%lf %lf %lf",&house.x1,&house.x2,&house.y )==3)
    {
        int n,flag = 0,cnt=0;
           if(dcmp(house.x1)==0&&dcmp(house.x2)==0&&dcmp(house.y)==0 ) break;
           scanf( "%lf %lf %lf",&pro.x1, &pro.x2,&pro.y );
           scanf( "%d",&n );
           for( int i = 0; i < n ; i++ )
           {
            scanf( "%lf %lf %lf",&line[i].x1,&line[i].x2,&line[i].y );
            if( dcmp(line[i].y - house.y) ==0 )
            {
               if( dcmp( line[i].x1 - house.x2 ) <= 0 && dcmp( line[i].x2 - house.x1 ) >= 0 )
                    flag = 1;    
            }
            else if( line[i].y < house.y && line[i].y > pro.y )line[cnt++] = line[i];        
        }
        if( flag ) printf( "No View\n" );
        else
        {
            if( cnt == 0 ) printf( "%.2f\n",pro.x2-pro.x1 );
            else
            {  
                sort( line , line + cnt , cmp );
                double view = Solve( cnt );
                if( dcmp( view )==0 ) printf( "No View\n" );
                else printf( "%.2f\n",view ); 
            }
        }
    }
    //system( "pause" );
    return 0;
}

 

posted @ 2012-07-11 17:52  wutaoKeen  阅读(146)  评论(0编辑  收藏  举报