POJ 2826 || an easy problem ?!(未AC,呵呵~

微笑今日未AC,來日再戰,頭腦混沌。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-8;
int dcmp( double x )
{
    if( fabs(x)<eps)
        return 0;
    return x < 0 ? -1: 1;
}

//================= 點結構 ===============
struct pnode
{
    double x,y;
    pnode( double a=0.0,double b=0.0):x(a),y(b){}

    // X乘重載
    double operator ^ (const pnode &b)const
    {
        return x*b.y - b.x*y;
    }

    pnode operator - ( const pnode &b)const
    {
        return pnode( x-b.x,    y-b.y);
    }

    pnode operator * (const double p)const
    {
        return pnode( x*p,   y*p );
    }

    pnode operator + (const pnode&b)const
    {
        return pnode( x+b.x, y+b.y );
    }

    bool operator == (const pnode&b)const
    {
        return dcmp( x-b.x )== 0 && dcmp( y-b.y )==0;
    }

    bool operator < (const pnode&b)const
    {
        return x < b.x || ( dcmp( x-b.x )==0 && y<b.y );
    }

    bool operator > (const pnode&b)const
    {
        return x > b.x || ( dcmp( x-b.x )==0 && y>b.y );
    }
};
//================ 線結構 ==============
typedef pnode myvec;
struct pline
{
    pnode st,ed;//st:起始點 ed:終點
    myvec vec;//向量
    pline(){}

    pline(pnode a,pnode b):st(a),ed(b)
    {
        vec = pnode(b-a);
    }
    void pread()
    {
        scanf("%lf %lf %lf %lf",&st.x,&st.y,&ed.x,&ed.y);
        if( ed.y > st.y)
            swap(st,ed);
        vec = pnode(ed-st);
    }
};

double cross( pnode p0,pnode p1,pnode p2)
{
    return (p1-p0) ^ (p2-p0);
}
double cross(pline a,pline b)
{
    return (a.ed-a.st)^(b.ed-b.st);
}

/*
    點乘:
        dot(v,w) == 二者長度乘積再乘上他們夾角的餘弦
        夾角:從 v 到 w 逆時針旋轉的角
*/
double dot( myvec v,myvec w)
{
    return v.x*w.x + v.y*w.y;
}
bool seg_inter_seg(pline a,pline b)
{

    return
        max( a.st.x, a.ed.x) >=  min( b.st.x, b.ed.x)
    &&
        max( b.st.x, b.ed.x) >=  min( a.st.x, a.ed.x)
    &&
        max( a.st.y, a.ed.y) >=  min( b.st.y, b.ed.y)
    &&
        max( b.st.y, b.ed.y) >=  min( a.st.y, a.ed.y)
    &&//以上端點判斷
        dcmp(cross( a.st, a.ed, b.st ))*dcmp(cross( a.st, a.ed, b.ed ))<=0
    &&  dcmp(cross( b.st, b.ed, a.st ))*dcmp(cross( b.st, b.ed, a.ed ))<=0;
}
pnode get_line_inter_point(pline v,pline w)
{
    pline u (w.st,v.st);
    double t = cross( w,u )/cross(v,w);
    return v.st + (v.ed-v.st) * t;
}
bool seg_inter_line(pline line,pline seg)
{
    return ( dcmp( cross( seg.st,line.st,line.ed ) ) * dcmp( cross( seg.ed,line.st,line.ed) ) )<=0;
}
int check(pline a,pline b,pnode &p1,pnode &p2)
{
    pnode getit;
    pline ay (a.st,pnode(a.st.x+100,a.st.y));
    pline by (b.st,pnode(b.st.x+100,a.st.y));
    if( seg_inter_line(ay,b))
    {
        pline ax(a.st,pnode(a.st.x,10000 ));
        if( seg_inter_seg(ax,b))
            return 0;
        p1 = get_line_inter_point(ay,b);
        p2 = a.st;
        return 1;
    }
    if( seg_inter_line(by,a))
    {
        pline bx(b.st,pnode(b.st.x,10000 ));
        if( seg_inter_seg(bx,a))
            return 0;
        p1 = get_line_inter_point(by,a);
        p2 = b.st;
        return 1;
    }
    return 0;
}

pline a,b;
pline yl (pnode(0,0),pnode(0,100));
int main()
{
    int cas;
    scanf("%d",&cas);
    while( cas-- )
    {
        a.pread();
        b.pread();
        if( dcmp ( cross(a,b)) == 0 || dcmp(dot(yl.vec,a.vec))==0 || dcmp(dot(yl.vec,b.vec))==0 )
        {
            puts("0.00");
            //puts("1");
            continue;
        }
        pnode p = get_line_inter_point(a,b),p1,p2;
        int s = check(a,b,p1,p2);
        if( s==0 )
        {
            puts("0.00");
            //puts("2");
            continue;
        }
        double area = fabs ( cross(p,p1,p2)*0.5 );
        printf("%0.2f\n",area);

    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章