zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    C # 编码 习惯[转载]
    SilverLight 学习笔记 (一) 画刷:Brush
    55条SEO必备技巧
    c# 不安全代码之指针
    VMare 硬盘扩展和压缩、网络配置
    Win7 防护墙设置——Ping命令,Http访问
    Vs2010 sp1补丁太让人纠结
    不可小瞧的GetHashCode函数
    .NET中颜色的转换方法总结
    VS2010 如何制作项目模板
  • 原文地址:https://www.cnblogs.com/mrha/p/8168393.html
Copyright © 2011-2022 走看看