• [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;
    }
    
  • 相关阅读:
    04月06日总结
    04月07日总结
    03月27日总结
    04月04日总结
    网络编程:阻塞I/O和线程模型
    网络编程:非阻塞I/O
    网络编程:阻塞I/O和进程模型
    bool型返回值函数,没写return语句的时候返回啥?
    网络编程:C10K问题
    网络编程:epoll
  • 原文地址:https://www.cnblogs.com/mrha/p/8168393.html
Copyright © 2020-2023  润新知