zoukankan      html  css  js  c++  java
  • poj3304 Segments

    Segments
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 15967   Accepted: 5063

    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!

    Source

    大致题意:给一些线段,问有没有一条直线,使得这些线段的投影在直线上有公共点.
    分析:投影实际上就是做垂线,如果一条直线穿过所有线段,做这条直线的垂线,垂足就是公共点.这是问题的第一步转化.那么这条直线怎么求呢?两点确定一条直线,这个点有无穷多个,不太好确定.事实上这两个点可以由线段的任意两个端点确定.为什么呢.假设一条直线穿过了所有的线段,每条线段就是阻碍点.直线可以在线段上自由挪动,旋转,直到碰到阻碍点.感性地理解一下,如果一条直线穿过两个端点并且穿过所有线段,那么它就是满足条件的,不会有这种情况:没有穿过两个端点的直线穿过所有线段,却有穿过所有线段的直线.那么就很好做了,枚举两个端点,利用叉积判断.
               坑点:n = 1特判掉.
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int T,n;
    bool flag = false;
    const double eps = 1e-8;
    
    struct node
    {
        double x,y;
    };
    
    struct node2
    {
        node p1,p2;
    }e[110];
    
    node sub(node a,node b)
    {
        node temp;
        temp.x = a.x - b.x;
        temp.y = a.y - b.y;
        return temp;
    }
    
    double det(node a,node b)
    {
        return a.x * b.y - a.y * b.x;
    }
    
    void check(node a,node b)
    {
        if (sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) < eps)
            return;
        for (int i = 1; i <= n; i++)
        {
            double temp1 = det(sub(b,a),sub(e[i].p1,a));
            double temp2 = det(sub(b,a),sub(e[i].p2,a));
            if (temp1 * temp2 > eps)
                return;
        }
        flag = true;
    }
    
    int main()
    {
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            flag = false;
            for (int i = 1; i <= n; i++)
                scanf("%lf%lf%lf%lf",&e[i].p1.x,&e[i].p1.y,&e[i].p2.x,&e[i].p2.y);
            if (n <= 2)
            {
                puts("Yes!");
                continue;
            }
            for (int i = 1; i <= n; i++)
            {
                for (int j = i + 1; j <= n; j++)
                {
                    check(e[i].p1,e[j].p1);
                    check(e[i].p1,e[j].p2);
                    check(e[i].p2,e[j].p1);
                    check(e[i].p2,e[j].p2);
                    if (flag)
                        break;
                }
                if (flag)
                    break;
            }
            if (flag)
                puts("Yes!");
            else
                puts("No!");
        }
    
        return 0;
    }
  • 相关阅读:
    JavaBean 与 EJB 的区别
    MFC选项卡的实现
    MFC的图片按钮
    windows 下使用 MinGW + msys 编译 ffmpeg
    在windows使用vs2008编译live555
    C89 和 C99 标准比较
    11.求二元查找树的镜像[MirrorOfBST]
    10.排序数组中和为给定值的两个数字[Find2NumbersWithGivenSum]
    9.链表中倒数第k个结点[FindReverseKthLinkedListNode]
    8.另类方法求1+2+...+n[AnotherMethodOfCalculateSumN]
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8098258.html
Copyright © 2011-2022 走看看