[poj] 3304 Segments || 判断线段相交

Posted Mrha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[poj] 3304 Segments || 判断线段相交相关的知识,希望对你有一定的参考价值。

原题

给出n条线段,判断是否有一条直线与所有线段都有交点


若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件。
每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点。

判断交点:
判断AB和CD是否相交,即判断AC×BD(叉积)和AD×BC(叉积)是否同号

#include<cstdio>
#define eps 1e-13
#define N 110
using namespace std;
int t,n;
struct point
{
    double x,y;
    point() {}
    point(double _x,double _y) : x(_x),y(_y) {}
    double operator * (const point &b) const
    {
        return x*b.y-b.x*y;
    }
    point operator - (const point &b) const
    {
        return point(b.x-x,b.y-y);
    }
    bool operator == (const point &b) const
    {
        return x==b.x && y==b.y;
    }
    void read()
    {
        scanf("%lf%lf",&x,&y);
    }
};
struct hhh
{
    point s,t;
}a[N];

bool check(point aa,point bb)
{
    if (aa==bb) return 0;
    for (int i=1;i<=n;i++)
    if (((aa-a[i].s)*(aa-bb))*((aa-a[i].t)*(aa-bb))>eps) return 0;
    return 1;
}

bool solve()
{
    for (int i=1;i<=n;i++)
    for (int j=i+1;j<=n;j++)
        if (check(a[i].s,a[j].t) || check(a[j].s,a[i].t)) return 1;
        else if (check(a[i].s,a[j].s) || check(a[i].t,a[j].t)) return 1;
    return 0;
}

int main()
{
    scanf("%d",&t);
    while (t--)
    {
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        a[i].s.read(),a[i].t.read();
    if (n<3 || solve()) puts("Yes!");
    else puts("No!");
    }
    return 0;
}

以上是关于[poj] 3304 Segments || 判断线段相交的主要内容,如果未能解决你的问题,请参考以下文章

[poj] 3304 Segments || 判断线段相交

POJ 3304 Segments(判断直线与线段是否相交)

Segments---poj3304(判断直线与线段的位置关系)

POJ 3304 Segments (叉乘判断线段相交)

POJ3304 Segments

POJ 3304 Segments