• 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
  • 相关阅读:
    初心不负 笔记-JS高级程序设计-引用类型篇-Array
    CSS-样式篇
    笔记-JS高级程序设计-变量,作用域和内存问题
    笔记-JS高级程序设计-基本概念篇
    WPF 10天修炼 第四天- WPF布局容器
    WPF 10天修炼 第三天- Application全局应用程序类
    WPF 10天修炼 第二天- XAML语言
    WPF 10天修炼 第一天- 入门
    C# 关于e.Handled 的说明
    C# Replace方法
  • 原文地址:https://www.cnblogs.com/l999q/p/9544944.html
Copyright © 2020-2023  润新知