码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-01-01 20:34:58      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:pac   str   def   body   else   div   eps   poi   ++   

原题

给出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 || 判断线段相交

标签:pac   str   def   body   else   div   eps   poi   ++   

原文地址:https://www.cnblogs.com/mrha/p/8168393.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!