POJ 2826 An Easy Problem?!

来源:互联网 发布:盘古数据科技有限公司 编辑:程序博客网 时间:2024/05/18 02:37

好坑的题

思路超简单,实现好麻烦

刚开始自己写了个,然后一直WA

就直接用别人的代码了

以后再也不写这种题

#include<iostream>  #include<algorithm>  #include<cmath>  #include<cstdio>  #include<complex>  #include<cstring>  #include<string>  #include<iomanip>         using namespace std;  #define max(a,b)  (a>b?a:b)  #define min(a,b)  (a<b?a:b)  #define eps 1e-8  #define zero(x)   (((x)>0?(x):-(x))<eps)      struct point{double x,y;};  struct line {point a,b;};    int n;  line l1,l2,l3;    double triangleArea(point a,point b,point c)   //求面积   {      double k=a.x*b.y+b.x*c.y+c.x*a.y              -b.x*a.y-c.x*b.y-a.x*c.y;      return k>0?k/2:-k/2;  }    int sig(double k)    {        if(fabs(k)<eps)          return 0;      return (k>0)?1:-1;    }        double det(double x1, double y1, double x2, double y2)    {        return x1 * y2 - x2 * y1;    }      double xmult(point p0,point p1,point p2)    {        return det(p1.x-p0.x,p1.y-p0.y,p2.x-p0.x,p2.y-p0.y);     }        double dotdet(double x1,double y1,double x2,double y2)    {        return x1*x2+y1*y2;    }        double dot(point p0, point p1, point p2)    {        return dotdet(p1.x-p0.x,p1.y-p0.y,p2.x-p0.x,p2.y-p0.y);    }        int between(point p0,point p1, point p2)    {        return sig(dot(p0,p1,p2));    }        int intersect1(point a, point b, point c, point d) //判断线段相交   {        double s1, s2, s3, s4;        int d1 = sig(s1 = xmult(a, b, c));        int d2 = sig(s2 = xmult(a, b, d));        int d3 = sig(s3 = xmult(c, d, a));        int d4 = sig(s4 = xmult(c, d, b));        if ((d1^d2) == -2 && (d3^d4) == -2)        {         return 1;        }        if (d1 == 0 && between(c, a, b) <= 0) return 2;        if (d2 == 0 && between(d, a, b) <= 0) return 2;        if (d3 == 0 && between(a, c, d) <= 0) return 2;        if (d4 == 0 && between(b, c, d) <= 0) return 2;        return 0;    }    bool parallel(const line &u,const line &v)    //判断两条直线是否平行   x1y2-y1x2=0   {      return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));  }      point intersection(line &u ,line &v)         //求两条直线的交点   {      point temp=u.a;      double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))               /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));      temp.x+=(u.b.x-u.a.x)*t;      temp.y+=(u.b.y-u.a.y)*t;      return temp;  }    bool hide(line u,line v,point in)   //判断是否有入口被遮住的情况   {      point temp1,temp2;      temp1=(u.a.y>=v.a.y?u.a:v.a);      temp2=(u.a.y>=v.a.y?v.a:u.a);      if(temp1.x<=temp2.x && temp2.x<in.x &&xmult(in,temp1,temp2)>eps)          return true;      if(temp1.x>=temp2.x && temp2.x>in.x &&xmult(in,temp1,temp2)<eps)          return true;      return false;        }      void init()  {      scanf("%lf%lf%lf%lf",&l1.a.x,&l1.a.y,&l1.b.x,&l1.b.y);      scanf("%lf%lf%lf%lf",&l2.a.x,&l2.a.y,&l2.b.x,&l2.b.y);        if(l1.a.y<l1.b.y)          swap(l1.a,l1.b);      if(l2.a.y<l2.b.y)          swap(l2.a,l2.b);        }    double solve()  {      line ll;      ll.a.x=ll.a.y=0;      ll.b.x=1;      ll.b.y=0;       point temp,temp2;      if(parallel(l1,l2))//两条线平行 ,重合           return 0.00;      if(parallel(ll,l2)||parallel(ll,l1))  //某条线水平           return 0.00;      if(intersect1(l1.a,l1.b,l2.a,l2.b)!=1&&intersect1(l1.a,l1.b,l2.a,l2.b)!=2) //两条线不想交           return 0.00;      temp=(l1.a.y<l2.a.y?l1.a:l2.a);      l3.b=temp;      temp.x-=10000;      l3.a=temp;      temp=intersection(l1,l2);  //交点与较低点一样高,就是平行 和  交点为一块板的较高点       if(temp.y>=l1.a.y || temp.y>=l2.a.y)          return 0.00;      if(hide(l1,l2,temp))     //较高点不能遮住较低点           return 0.00;       if(l1.a.y>=l2.a.y)       //选点,注意不要选错,因为两点y相等时选取的最低点是右边的点,所以 计算出的水平线交点应该与左边相交。           temp2=intersection(l1,l3);      else          temp2=intersection(l2,l3);      return triangleArea(l3.b,temp,temp2);  }    int main()  {            cin>>n;      while(n--)      {          init();          cout<<setprecision(2)<<setiosflags(ios::fixed)<<solve()<<endl;      }      return 0;  }  


0 0
原创粉丝点击