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\n",ans);
    }
    return 0;
}
时间: 2024-08-26 01:36:47

POJ 2826 An Easy Problem? 判断线段相交的相关文章

POJ 2826 An Easy Problem?!(线段相交,分类讨论)

题意:给两个线段,问他们能收集到多少雨水. 链接:http://poj.org/problem?id=2826 解法:分四种情况讨论 1. 存在一个线段与x轴平行,答案为0 2. 两个线段没有交点,答案为0 3. 1和2都不满足时,令线段1为比较低的那个线段,且p1为其比较高的那个点,若该点往y轴正方向的射线与线段2有交点,则答案为0 4. 3不满足时,求出两线段交点x1,p1做一条平行于x轴的线,该线与线段2的交点x2,则三角形x1, x2, p1的面积就是答案 小结:此题属于分类讨论型的题,

【POJ 2653】Pick-up sticks 判断线段相交

一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 using namespace std; struct Point { double x

Poj 2826 An Easy Problem?!

地址:http://poj.org/problem?id=2826 题目: An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13016   Accepted: 2003 Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Ben nails tw

POJ 2826 An Easy Problem?! 好题

题目大意就是两根木块组成一个槽,问槽里能装多少雨水,注意雨水垂直落下,思路也很简单,就是分类讨论有点糟. 1.如果两条线段不相交或者平行,则装0: 2.有一条平行x轴,装0: 3.若上面覆盖下面的,装0: 4.其它,叉积求面积. 直接上代码: #include <iostream> #include <cmath> #include <stdio.h> using namespace std; const double eps=1e-8; struct point{ d

POJ 2826 An Easy Problem?!(计算几何)

An Easy Problem?! Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10533   Accepted: 1589 Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Ben nails two wooden boards on the wall of his bar

POJ 2826 An Easy Problem?!(计算几何)

基本就和网上题解一样的思路,把几种情况判掉blablabla..就WA了. 然后答案加个EPS就过了.显然这题没有写SPJ..卡了精度 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; struct Point { double x, y; Point() {} Point(double x, double y

简单几何(线段相交) POJ 2826 An Easy Problem?!

题目传送门 题意:两条线段看成两块木板,雨水从上方往下垂直落下,问能接受到的水的体积 分析:恶心的分类讨论题,考虑各种情况,尤其是入口被堵住的情况,我的方法是先判断最高的两个点是否在交点的同一侧,然后看看是否高的点覆盖了低的点,用叉积判断方向,其他的情况见网上的解释.貌似没有什么卡精度的数据.最后膜拜楼教主,难以望其项背... /************************************************ * Author :Running_Time * Created Ti

poj 2653 Pick-up sticks(判断线段相交)

Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11043   Accepted: 4119 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to fin

POJ 2826 An Easy Problem!(简单数论)

Description Have you heard the fact "The base of every normal number system is 10" ? Of course, I am not talking about number systems like Stern Brockot Number System. This problem has nothing to do with this fact but may have some similarity. Y