POJ 2826(巨恶心的几何题,不过这题还是很锻炼找错的能力的)

一开始的时候分析对了,不过老是WA。。。。。。唉,后来找了点测试数据,照我原来的想法应该是可以的装水的,不过输出却是0.00.。。。。

呃,好吧,慢慢找错。。

我就大致总结下,哪些地方有可能犯错:

1.2个线段共线的情况。

 

2.计算积水面积的时候不能只选择y小的那个,要考虑y如果相等的话呢。(我就是被这卡了)

3.在考虑一块木板是否被另一块挡住的时候,我是这样考虑的:如果2个线段y较大的点组成的线段,如果不严格跨立y轴,则肯定可以积水。。(排除2个线段中存在一个平行X轴,2线段共线,及其中一个线段的点在另一个线段上,也就是2个线段严格相交的情况,这里的线段是指题目开始给出的线段)。反之,选择在另一个线段下面的线段,比较下X绝对值。就能判断是否挡住了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<fstream>
#define EPS 1e-13
using namespace std;
struct point {
  int ix,iy;
  double dx,dy; 
  point(){}
  point(double _dx, double _dy):dx(_dx),dy(_dy){}
  void ini()
  {
    dx = ix;
    dy = iy;  
  } 
}fir[2],sec[2];

double cmp(double x)
{
  if (x < 0)return -1;
  if (x > 0)return 1;
  return 0;  
}

int cmp(int x)
{
  if (x < 0)return -1;
  if (x > 0)return 1;
  return 0;  
}

point max(const point &p, const point &q)
{
  if (p.dy < q.dy) {
    return q;  
  } else {
    return p;  
  }  
}

point min(const point &p, const point q)
{
  if (p.dy < q.dy) {
    return p;  
  } else {
    return q;  
  } 
}

double dcross(const point &p1, const point &p2, const point &q1, const point &q2)
{
  return cmp((q2.dy - q1.dy)*(p2.dx - p1.dx) - (q2.dx - q1.dx)*(p2.dy - p1.dy));  
}

int icross(const point &p1, const point &p2, const point &q1, const point &q2)
{
  return cmp((q2.iy - q1.iy)*(p2.ix - p1.ix) - (q2.ix - q1.ix)*(p2.iy - p1.iy));  
}

point intersection(const point &p, const point &q1, const point &q2)
{
  return point((q1.dx - q2.dx)*(p.dy - q2.dy)/(q1.dy - q2.dy) + q2.dx, p.dy);  
}

void get_line(const point &p, const point &q, double &k, double &b)
{
  k = (q.dy - p.dy)/(q.dx - p.dx);
  b = q.dy - q.dx*k;  
}

point get_point(const point &p1, const point &p2, const point &q1, const point &q2) //注意共线情况 
{
  double k1,k2,b1,b2;
  if (p1.ix == p2.ix) {
    get_line(q1,q2,k1,b1);
    return point(p1.dx,p1.dx*k1+b1);     
  } else {
    if (q1.ix == q2.ix) {
      get_line(p1,p2,k1,b1);
      return point(q1.dx,q1.dx*k1+b1);
    } else {
      get_line(p1,p2,k1,b1);
      get_line(q1,q2,k2,b2);
      return point((b2 - b1)/(k1 - k2),k1*(b2 - b1)/(k1 - k2) + b1);  
    }   
  } 
}

bool on_seg(const point &p1, const point &p2, const point &q)
{
  if (min(p1.ix,p2.ix) <= q.ix && q.ix <= max(p1.ix,p2.ix) &&
      min(p1.iy,p2.iy) <= q.iy && q.iy <= max(p1.iy,p2.iy) &&
      icross(p1,p2,p1,q) == 0) {
    return true;      
  }  
  return false;
}

bool intersect(const point &p1, const point &p2, const point &q1, const point &q2)
{
  if (icross(p1,p2,p1,q1) == 0 && icross(p1,p2,p1,q2) == 0)return false; 
  if (on_seg(p1,p2,q1) || on_seg(p1,p2,q2) || on_seg(q1,q2,p1) || on_seg(q1,q2,p2))return true;
  if (icross(p1,q1,p1,p2)*icross(p1,p2,p1,q2) > 0 && icross(q1,p1,q1,q2)*icross(q1,q2,q1,p2) > 0)return true;
  return false;    
}

bool law()
{
  if (fir[0].iy == sec[0].iy || fir[1].iy == sec[1].iy)return false;
  if (!intersect(fir[0],sec[0],fir[1],sec[1]))return false;
  point start = get_point(fir[0],sec[0],fir[1],sec[1]);
  for (int i(0); i<2; ++i) {
    fir[i].dx -= start.dx;
    fir[i].dy -= start.dy;
    sec[i].dx -= start.dx;
    sec[i].dy -= start.dy;  
  }
  if (max(fir[1],sec[1]).dy < EPS && max(fir[1],sec[1]).dy > -EPS)return false;
  if (max(fir[0],sec[0]).dy < EPS && max(fir[0],sec[0]).dy > -EPS)return false;
  start.dx = start.dy = 0.00; 
  point one(0,1);
  if (dcross(start, max(fir[0],sec[0]), start, one)*dcross(start, one, start, max(fir[1],sec[1])) > -EPS) {
    return true;
  } else {
    if (dcross(start,max(fir[0],sec[0]),start,max(fir[1],sec[1])) > EPS) {
      if (max(fir[1],sec[1]).dx > EPS && max(fir[0],sec[0]).dx > EPS && fabs(max(fir[1],sec[1]).dx) < fabs(max(fir[0],sec[0]).dx) - EPS){
        return true;  
      } else {
        if (max(fir[1],sec[1]).dx < -EPS && max(fir[0],sec[0]).dx < -EPS && fabs(max(fir[1],sec[1]).dx) > EPS + fabs(max(fir[0],sec[0]).dx)) {
          return true;  
        }  
      }
    } else {
      if (max(fir[1],sec[1]).dx < -EPS && max(fir[0],sec[0]).dx < -EPS && fabs(max(fir[1],sec[1]).dx) < fabs(max(fir[0],sec[0]).dx) - EPS) {
        return true;  
      } else {
        if (max(fir[1],sec[1]).dx > EPS && max(fir[0],sec[0]).dx > EPS && fabs(max(fir[1],sec[1]).dx) > EPS + fabs(max(fir[0],sec[0]).dx)) {
          return true;  
        }  
      }
    }    
  }
  return false;  
}      


int main()
{
  int n;
  scanf("%d",&n);
  while (n--) {
    for (int i(0); i<2; ++i) {
      scanf("%d%d%d%d",&fir[i].ix,&fir[i].iy,&sec[i].ix,&sec[i].iy); 
      fir[i].ini();sec[i].ini(); 
    }  
    if (law()) {
      point one = max(fir[0],sec[0]);
      point two = max(fir[1],sec[1]);
      point result;
      double ans;
      if (one.dy > two.dy) {
        result = intersection(two,fir[0],sec[0]);
        ans = fabs(result.dx - min(one,two).dx)*min(one,two).dy/2.0;  
      } else {
        if (one.dy < two.dy) {
          result = intersection(one,fir[1],sec[1]);
          ans = fabs(result.dx - min(one,two).dx)*min(one,two).dy/2.0;
        } else {
          if (fabs(one.dx) > fabs(two.dx)) {
            ans = fabs(one.dx - two.dx)*two.dy/2.0;  
          } else {
            ans = fabs(two.dx - one.dx)*one.dy/2.0;  
          } 
        } 
      }
      printf("%.2lf\n",ans);
    } else {
      printf("0.00\n");  
    }
  }
  return 0;  
}

  

posted on 2012-05-16 16:25  Dev-T  阅读(846)  评论(1编辑  收藏  举报