POJ 2826 An Easy Problem?!

一个对精度要求比较高的题。

如果两个线段没交点,那么肯定是0。有交点也不一定就有水,水可以进不来。

最后答案要加一个eps,防止出现-0.00的答案

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<list>
#include<algorithm>
using namespace std;

struct point
{
    double x;
    double y;
    point(){}
    point(double a,double b){x=a;y=b;}
};
struct Line
{
    double a,b,c;
}line1,line2;

double a,b,c,d,e,f,g,h;
vector<point>v;
int T;

const double eps=1e-8;
#define zero(x)(((x)>0?(x):(-x))<eps)

double Area(point p0,point p1,point p2)
{
    return fabs((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y))/2.0;
}

double xmult(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

int dots_inline(point p1,point p2,point p3)
{
    return zero(xmult(p1,p2,p3));
}

int same_side(point p1,point p2,point l1,point l2)
{
    return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;
}

int dot_online_in(point p,point l1,point l2)
{
    return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}

int intersect_in(point u1,point u2,point v1,point v2)
{
    if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2)) return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);
    return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}

point jiaodian(double a,double b,double c,double d,double e,double f,double g,double h)
{
    double X1=a,Y1=b,X2=c,Y2=d,X3=e,Y3=f,X4=g,Y4=h;
    line1.a=Y2-Y1;
    line1.b=X2-X1;
    line1.c=Y2*(X2-X1)-X2*(Y2-Y1);

    line2.a=Y4-Y3;
    line2.b=X4-X3;
    line2.c=Y4*(X4-X3)-X4*(Y4-Y3);

    double ansX=1.0*(line1.b*line2.c-line2.b*line1.c)/(line1.a*line2.b-line2.a*line1.b);
    double ansY=-1.0*(line2.a*line1.c-line1.a*line2.c)/(line1.a*line2.b-line2.a*line1.b);

    point ret(ansX,ansY);
    return ret;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
        scanf("%lf%lf%lf%lf",&e,&f,&g,&h);
        point p1(a,b);point p2(c,d);
        point p3(e,f);point p4(g,h);

        double ans=0.00000;
        if(intersect_in(p1,p2,p3,p4))
        {
            point jiao=jiaodian(a,b,c,d,e,f,g,h);
            v.clear();

            if(p1.y>jiao.y&&fabs(p1.y-jiao.y)>eps) v.push_back(p1);
            if(p2.y>jiao.y&&fabs(p2.y-jiao.y)>eps) v.push_back(p2);
            if(p3.y>jiao.y&&fabs(p3.y-jiao.y)>eps) v.push_back(p3);
            if(p4.y>jiao.y&&fabs(p4.y-jiao.y)>eps) v.push_back(p4);


            if(v.size()==2)
            {
                if((v[0].x<=jiao.x&&v[1].x>=jiao.x)||(v[1].x<=jiao.x&&v[0].x>=jiao.x))
                {
                    if(v[0].y>v[1].y) swap(v[0],v[1]);
                    point jiao2=jiaodian(v[0].x,v[0].y,20000,v[0].y,jiao.x,jiao.y,v[1].x,v[1].y);
                    ans=Area(jiao,jiao2,v[0]);
                }
                else
                {

                    if(fabs((v[0].y-jiao.y)/(v[0].x-jiao.x))<fabs((v[1].y-jiao.y)/(v[1].x-jiao.x)))
                        swap(v[0],v[1]);

                    if(fabs(v[0].x-jiao.x)>=fabs(v[1].x-jiao.x)){}
                    else
                    {
                        if(v[0].y>v[1].y) swap(v[0],v[1]);
                        point jiao2=jiaodian(v[1].x,v[1].y,jiao.x,jiao.y,v[0].x,v[0].y,20000,v[0].y);
                        ans=Area(jiao,jiao2,v[0]);
                    }
                }
            }
        }
        printf("%.2f\n",ans+eps);
    }

    return 0;
}

 

posted @ 2016-01-23 13:28  Fighting_Heart  阅读(164)  评论(0编辑  收藏  举报