POJ 3304 Segments(叉积的简单运用,直线和线段的相交判断)

POJ 3304 Segments

思路:构造一条直线能经过所有的线段,这些交点的投影将会是一个公共的点。

然后就是利用叉乘判断直线与线段是否有交点,以及一个非常重要的思路就是枚举所有线段的任意两个端点来构造这条直线。

如果存在这样子一条直线,那么这条直线在所有线段中平移、旋转(在与所有线段相交的情况下),可以碰到线段中的两个端点。

在这里插入图片描述

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
double eps = 1e-8;

struct Point
{
    double x,y;
    Point(double xx= 0, double yy = 0):x(xx), y(yy){}
}p[100000];
typedef Point Vector;
struct Line
{
    Point a, b;
    Line(){}
    Line(Point aa, Point bb):a(aa),b(bb){}
}line[100000];
int sgn(double x){
    if(fabs(x) < eps)
        return 0;
    if(x < 0)
        return -1;
    return 1;
}
bool operator == (const Point& a, const Point& b){
    if(sgn(a.x-b.x) == 0 && sgn(a.y-b.y) == 0)
        return true;
    return false;
}
Vector operator-(Point A, Point B)
{
    return Vector(A.x-B.x, A.y-B.y);
}
double Cross(Vector A, Vector B)
{
    return A.x*B.y - A.y*B.x;
}

bool LineIntersection(Point a, Point b, Point c, Point d)
{

    return Cross( b-a,c-a)*Cross( b-a,d-a) <=0;
}

bool check(Point a, Point b, int n)
{

    for(int i = 0;i<n;i++)
    {
        if(!LineIntersection(a, b, line[i].a,line[i].b))
            return false;
    }
    return true;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n,cnt = 0;
        double x1,x2,y1,y2;
        scanf("%d", &n);
        for(int i = 0;i<n;i++)
        {
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            line[i] = Line(Point(x1,y1),Point(x2,y2));
            p[cnt++]= Point(x1,y1);
            p[cnt++] =Point(x2,y2);

        }
        bool flag = false;

        for(int i = 0;i<cnt;i++)
        {
            flag = false;
            for(int j = i+1;j<cnt;j++)
            {

                if(p[i] == p[j])
                    continue;

                if(check(p[i],p[j],n))
                    flag = true;


                if(flag)break;
            }
            if(flag) break;
        }
        if(flag) printf("Yes!\n");
        else
            printf("No!\n");
    }
    return 0;
}

图片来源:[(17条消息) POJ - 3304 – Segments【直线与线段相交 】_星空皓月的博客-CSDN博客_直线与线段相交]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值