zoukankan      html  css  js  c++  java
  • POJ 3304 Segments(判断直线与线段是否相交)

    题目传送门:POJ 3304 Segments

    Description

    Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common.

    Input

    Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing a positive integer n ≤ 100 showing the number of segments. After that, n lines containing four real numbers x1 y1 x2 y2 follow, in which (x1y1) and (x2y2) are the coordinates of the two endpoints for one of the segments.

    Output

    For each test case, your program must output "Yes!", if a line with desired property exists and must output "No!" otherwise. You must assume that two floating point numbers a and b are equal if |a - b| < 10-8.

    Sample Input

    3
    2
    1.0 2.0 3.0 4.0
    4.0 5.0 6.0 7.0
    3
    0.0 0.0 0.0 1.0
    0.0 1.0 0.0 2.0
    1.0 1.0 2.0 1.0
    3
    0.0 0.0 0.0 1.0
    0.0 2.0 0.0 3.0
    1.0 1.0 2.0 1.0

    Sample Output

    Yes!
    Yes!
    No!

    题目大意:

      在一个平面上,给你n个线段,问是否存在一条直线,使得将这些线段投影到上面之后,所有投影线段至少有一个共同点。

    解题思路:

      若存在一条直线使得所有线段投影到上面之后其投影至少有一个公共点,则这条直线必有一条垂线与所有线段都相交。

      这题就转化为了求是否存在一条直线与所有线段都相交。

      接下来我们只需枚举两个端点(不是同一直线上的)来找这条直线,若所有端点对的直线都不经过所有线段,则不存在这样的直线。

      我们的重点就是判断直线与线段是否相交。同时需要注意如果枚举的两个端点相等则为一个点不能确定直线和精度问题(题目说了是10-8)。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #define eps 1e-8
    using namespace std;
    const int N = 100 + 10;
    int dcmp(double x)
    {
        if(fabs(x)<eps) return 0;
        return x<0?-1:1;
    }
    struct point  ///
    {
        double x, y;
        point(double a = 0, double b = 0){ x = a, y = b;}
        point operator-(const point& b) const { return point(x - b.x, y - b.y);}
        double operator^(const point& b) const { return x * b.y - y * b.x; }
    } p[2*N];
    bool operator == (const point& a, const point& b)
    {
        return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
    }
    struct line  ///线
    {
        point s, e;
    } l[N];
    
    bool Line_Seg(point a1,point a2,line l)
    {
        double c1=((a1-a2)^(l.s-a2)),c2=((a1-a2)^(l.e-a2));
        return dcmp(c1)*dcmp(c2)<=0;
    }
    int num,n,T;
    bool judge()
    {
        for (int i=0; i<num; i++)
            for (int j=i+1,k; j<num; j++)
            {
                if (p[i]==p[j]) continue;
                for ( k=0; k<n; k++)
                    if (!Line_Seg(p[i],p[j],l[k]))
                        break;
                if (k>=n) return 1;
            }
        return 0;
    }
    
    int main()
    {
        for ( scanf("%d",&T); T; T--)
        {
            num=0;
            scanf("%d",&n);
            for (int i=0; i<n; i++)
            {
                scanf("%lf%lf%lf%lf",&l[i].s.x,&l[i].s.y,&l[i].e.x,&l[i].e.y);
                p[num++]=l[i].s;
                p[num++]=l[i].e;
            }
            if (judge()) printf("Yes!
    ");
            else printf("No!
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Mybatis类型转换介绍
    简单的快捷方式
    一位资深程序员大牛给予Java初学者的学习路线建议
    题目1014:排名-----------------------此题是一个坑----------------------------------结构体还是用纯c语言不要夹杂c++
    题目1013:开门人和关门人----没有AC掉
    题目1038:Sum of Factorials
    题目1036:Old Bill------简单的模拟
    九度 题目1031:xxx定律
    九度 题目1020:最小长方形
    九度 题目1006:ZOJ问题-----------------我没有A掉
  • 原文地址:https://www.cnblogs.com/l999q/p/9544944.html
Copyright © 2011-2022 走看看