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;
    }
    
  • 相关阅读:
    Android学习地址
    Android动画设计源码地址
    chromeWebBrowser之浏览器开发
    win8.1蓝屏解决
    打包应用程序
    win8.1解决鼠标右键反应慢的问题
    Rewrite服务器和robots文件屏蔽动态页面
    第08组 Alpha事后诸葛亮
    第08组 Alpha冲刺(6/6)
    第08组 Alpha冲刺(5/6)
  • 原文地址:https://www.cnblogs.com/mrha/p/8168393.html
Copyright © 2011-2022 走看看