zoukankan      html  css  js  c++  java
  • POJ 2826 An Easy Problem? 判断线段相交

    POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客

    下面三种情况比较特殊,特别是第三种

    G++怎么交都是WA,同样的代码C++A了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    const double INF = 1e5;
    
    int sgn(double x)
    {
        if(fabs(x) < eps) return 0;
        return x < 0 ? -1:1;
    }
    
    struct Point
    {
        double x,y;
        Point() {}
        Point(double _x,double _y)
        {
            x = _x,y = _y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x,y - b.y);
        }
        //叉积
        double operator ^(const Point &b)const
        {
            return x*b.y - y*b.x;
        }
        //点积
        double operator *(const Point &b)const
        {
            return x*b.x + y*b.y;
        }
    };
    
    struct Line
    {
        Point p,q;
        Line() {};
        Line(Point _p,Point _q)
        {
            p = _p,q = _q;
        }
        //两直线相交求交点
        //第一个值为0表示直线重合,为1表示平行,为2表示相交
        //只有第一个值为2时,交点才有意义
        pair<int,Point> operator &(const Line &b)const
        {
            Point res = p;
            if(sgn((p-q)^(b.p-b.q)) == 0)
            {
                if(sgn((p-b.q)^(b.p-b.q)) == 0)
                    return make_pair(0,res);//重合
                else return make_pair(1,res);//平行
            }
            double t = ((p-b.p)^(b.p-b.q))/((p-q)^(b.p-b.q));
            res.x += (q.x-p.x)*t;
            res.y += (q.y-p.y)*t;
            return make_pair(2,res);
        }
    };
    
    //*判断线段相交
    bool inter(Line l1,Line l2)
    {
        return
            max(l1.p.x,l1.q.x) >= min(l2.p.x,l2.q.x) &&
            max(l2.p.x,l2.q.x) >= min(l1.p.x,l1.q.x) &&
            max(l1.p.y,l1.q.y) >= min(l2.p.y,l2.q.y) &&
            max(l2.p.y,l2.q.y) >= min(l1.p.y,l1.q.y) &&
            sgn((l2.p-l1.q)^(l1.p-l1.q))*sgn((l2.q-l1.q)^(l1.p-l1.q)) <= 0 &&
            sgn((l1.p-l2.q)^(l2.p-l2.q))*sgn((l1.q-l2.q)^(l2.p-l2.q)) <= 0;
    }
    
    Point pot[105],peg;
    double rad;
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int t;
        double x1,y1,x2,y2;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            Line L1=Line(Point(x1,y1),Point(x2,y2));
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            Line L2=Line(Point(x1,y1),Point(x2,y2));
            if(sgn(L1.p.y - L1.q.y)==0 || sgn(L2.p.y - L2.q.y)==0)
            {
                puts("0.00");
                continue;
            }
            if(!inter(L1,L2))
            {
                puts("0.00");
                continue;
            }
            if(sgn(L1.p.y - L1.q.y) < 0) swap(L1.p,L1.q);
            if(sgn(L2.p.y - L2.q.y) < 0) swap(L2.p,L2.q);
            if(inter(Line(L1.p,Point(L1.p.x,INF)),L2))
            {
                puts("0.00");
                continue;
            }
            if(inter(Line(L2.p,Point(L2.p.x,INF)),L1))
            {
                puts("0.00");
                continue;
            }
            pair<int,Point> pr=L1 & L2;
            Point cp=pr.second;
            pr=Line(L1.p,Point(INF,L1.p.y)) & L2;
            double ans=fabs((L1.p-cp)^(pr.second-cp))/2;
            pr=Line(L2.p,Point(INF,L2.p.y)) & L1;
            ans=min(ans,fabs((L2.p-cp)^(pr.second-cp))/2);
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    uva 10491 Cows and Cars
    uva 10910 Marks Distribution
    uva 11029 Leading and Trailing
    手算整数的平方根
    uva 10375 Choose and divide
    uva 10056 What is the Probability?
    uva 11027 Palindromic Permutation
    uva 10023 Square root
    Ural(Timus) 1081. Binary Lexicographic Sequence
    扩展欧几里得(求解线性方程)
  • 原文地址:https://www.cnblogs.com/pach/p/7220927.html
Copyright © 2011-2022 走看看