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;
    }
  • 相关阅读:
    PHP从入门到精通——读书笔记(第20章:Zend Framwork框架)
    PHP从入门到精通——读书笔记(第21章:Smarty模板技术)
    PHP从入门到精通——读书笔记(第11—12章:Cookie和Session、图形图像技术等)
    love english
    PLC基础知识简介
    临时表的存储说明及它的删除
    化解字符串不能超过8000的方法及交叉表处理SQL2000
    常用英语口语绝佳句型100句
    一个表占用了多少磁盘空间的查询方法
    女孩都应该记住的几句英文
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8098258.html
Copyright © 2011-2022 走看看