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;

}

 

你可能感兴趣的:(poj)