Segments POJ - 3304

Segments

题目链接:https://vjudge.net/problem/POJ-3304

题目:

 

 

题意:问是否存在一条直线,使所有线段到这条直线的投影至少有一个交点。

思路:就是看有没有一条直线与所有的线段相交,由于数据很小,因此可以暴力求解,将题目给的所有点用结构体存起来,然后任意两个端点相连为一条直线,判断该直线是否与所有的线段相交即可,在设定为直线前先判断该两点之间距离是否小于1e-8,若小于则可以看作为一点,不可组成直线,继续与其他点成为直线,暴力判断。

 

// 
// Created by HJYL on 2020/1/12.
//
#include<stdio.h>
#include<math.h>
#include<string.h>

#define eps 1e-8
#define pi  3.141592653589793
const int maxn=1e5+10;

using namespace std;

struct Point{
    double x,y;
    Point(double a=0,double b=0){x=a;y=b;}
};

typedef Point Vector;

struct Line{
    double a,b,c,angle;
    Point p1,p2;
    Line(Point s,Point e)
    {
        a=s.y-e.y;
        b=e.x-s.x;
        c=s.x*e.y-e.x*s.y;
        angle=atan2(e.y-s.y,e.x-s.x);
        p1=s;p2=e;
    }
    Line(){}
};

struct Segment
{
    Point s,e;
    Segment(Point a,Point b){s=a;e=b;}
    Segment(double x1,double y1,double x2,double y2)
    {
        s=Point(x1,y1);
        e=Point(x2,y2);
    }
    Segment(){}
};

Vector operator + (Point a,Point b)
{
    return Vector(a.x+b.x,a.y+b.y);
}

Vector operator - (Point a,Point b)
{
    return Vector(a.x-b.x,a.y-b.y);
}

Vector operator * (Point a,double k)
{
    return Vector(a.x*k,a.y*k);
}

Vector operator / (Point a,double k)
{
    return Vector(a.x/k,a.y/k);
}

double Cross(Point &sp, Point &ep, Point &op)
{
    return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y);
}

double Cross(Vector a,Vector b)
{
    return a.x*b.y-b.x*a.y;
}

int epssgn(double x)
{
    if(fabs(x)<eps)
        return 0;
    else
        return x<0?-1:1;
}

double dis(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

int IsLineIntersectSegment(Point p1,Point p2,Point s,Point e)
{
    if (Cross(p1,p2,s)*Cross(p1,p2,e)>eps) return 0;
    else return 1;
}

int main()
{
    //freopen("text","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        Point ll[maxn];
        double xx,yy,xx1,yy1;
        int pos=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf%lf%lf",&xx,&yy,&xx1,&yy1);
            ll[pos].x=xx;ll[pos].y=yy;
            pos++;
            ll[pos].x=xx1;ll[pos].y=yy1;
            pos++;
        }
        if(n==1||n==2)
            printf("Yes!\n");
        else {
            bool ff=false;
            for (int i = 0; i < pos; i++) {
                for (int j = 0; j < pos; j++) {
                    if (i == j)
                        continue;
                    if (dis(ll[i], ll[j]) < eps)
                        continue;
                    bool flag = false;
                    for (int t = 0; t < n; t++) {
                        if(!IsLineIntersectSegment(ll[i],ll[j],ll[t*2],ll[t*2+1]))
                        {
                            flag=true;
                            break;
                        }
                    }
                    if(!flag)
                    {
                        ff=true;
                        break;
                    }
                }
                if(ff)
                    break;
            }
            if(ff)
                printf("Yes!\n");
            else
                printf("No!\n");
        }
        }
    return 0;
}

  

posted @ 2020-01-12 22:02  branna  阅读(138)  评论(0编辑  收藏  举报