poj 2826 An Easy Problem?!

 

这个题是要求钉两块木板接水,问你能接到多少水;

这里有几种情况不能接到水:

1 :两直线没焦点;2:一条直线是水平的,3 :上方没口子,4:上面的线段挡住了下面的线段使水不能落到里面去;

这里要用到定比分点。

 

 

 
View Code
View Code 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
class Point
{
public:
      double x,y;    
};
double Min( double a , double b )
{
      return a < b ? a : b;    
}
double segment( Point p1 , Point p2 , Point q )//叉积 
{
   return ( p1.x - q.x )*( p2.y - q.y ) - ( p2.x - q.x )*( p1.y - q.y );    
}
void Solve( Point A[] , Point B[] )
{
   double d1 = segment( A[0] ,A[1] , B[0] );
   double d2 = segment( A[0] ,A[1] , B[1] );
   double d3 = segment( B[0] ,B[1] , A[0] );
   double d4 = segment( B[0] ,B[1] , A[1] );
   if( d1*d2 <= 0 && d3*d4 <=0 )
   {
      Point point,C[2];
      //利用定比分点法求交点 
      point.x = ( fabs( d1 )*B[1].x + fabs( d2 )*B[0].x )/( fabs( d1 ) + fabs( d2 ));
      point.y = ( fabs( d1 )*B[1].y + fabs( d2 )*B[0].y )/( fabs( d1 ) + fabs( d2 ));
      double min_y = Min( A[1].y , B[1].y );
      C[0].x=(fabs(A[0].y-min_y)*A[1].x+fabs(A[1].y-min_y)*A[0].x)/(fabs(A[0].y-min_y)+abs(A[1].y-min_y));    
      C[0].y=(fabs(A[0].y-min_y)*A[1].y+fabs(A[1].y-min_y)*A[0].y)/(fabs(A[0].y-min_y)+abs(A[1].y-min_y));
      C[1].x=(fabs(B[0].y-min_y)*B[1].x+fabs(B[1].y-min_y)*B[0].x)/(fabs(B[0].y-min_y)+abs(B[1].y-min_y));    
      C[1].y=(fabs(B[0].y-min_y)*B[1].y+fabs(B[1].y-min_y)*B[0].y)/(fabs(B[0].y-min_y)+abs(B[1].y-min_y));
      if( C[0].x < C[1].x )
      {
          if( A[1].x >= B[1].x )//判断是否被上面的木板挡住 
          {    
              printf( "0.00\n" );
              return ;
          }    
      }    
      else if( A[1].x <= B[1].x )
           {  
               printf( "0.00\n" );
               return;
           }
      printf( "%.2f\n",fabs(segment( C[0],C[1] ,point )/2.0) );
   }
   else printf( "0.00\n" );      
}
int main(  )
{
    int N;
    while( scanf( "%d",&N )==1 )
    {
        while( N-- )
        {
           Point A[2],B[2];
           scanf( "%lf %lf %lf %lf",&A[0].x ,&A[0].y ,&A[1].x , &A[1].y );
           if( A[0].y > A[1].y ) swap( A[0] , A[1] );
           scanf( "%lf %lf %lf %lf",&B[0].x , &B[0].y ,&B[1].x ,&B[1].y );
           if( B[0].y > B[1].y ) swap( B[0] , B[1] );
           //判断是否平行 
           if( ( A[0].x - A[1].x )*( B[0].y - B[1].y ) - ( B[0].x - B[1].x )*( A[0].y - A[1].y ) ==0 )
                printf( "0.00\n" );
            //判断是否有一块木板水平 
           else if( A[0].y == A[1].y || B[0].y == B[1].y )
                printf( "0.00\n" );
                else Solve( A , B );
        }
    }
    return 0;    
}

 

posted @ 2012-07-08 17:10  wutaoKeen  阅读(135)  评论(0编辑  收藏  举报