poj 3304 直线与线段相交

Segments

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 12161   Accepted: 3847

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!
/*
poj 3304 直线与线段相交

给你n条线段,确定是否存在一条直线,它们的投影到上面时有公共点

如果存在一个这样的直线,那么说明所有的线段能和一条直线相交
对这条直线进行一定的旋转,必定与所有直线的端点中的至少两个相交
所以枚举所有的端点进行判断即可
//注意判断相同点

hhh-2016-05-04 20:48:26
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson  (i<<1)
#define rson  ((i<<1)|1)
typedef long long ll;
const int  maxn = 40010;
double eps = 1e-8;
int tot;
int n,m;
double x1,x2,y1,y2;

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

struct Point
{
    double x,y;
    Point() {}
    Point(double _x,double _y)
    {
        x = _x,y = _y;
    }
    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;
    }
};

struct Line
{
    Point s,t;
    Line() {}
    Line(Point _s,Point _t)
    {
        s = _s;
        t = _t;
    }
};
int tans[maxn];
Line line[maxn];
Point po[maxn];
Point p;

bool seg_inter_line(Line l1,Line l2)
{
    return sgn((l2.s-l1.t) ^ (l1.s-l1.t))*sgn((l2.t-l1.t)^(l1.s-l1.t)) <= 0;
}

bool cal(Line tl)
{
    for(int i = 0;i < n;i++)
    {
        if(!seg_inter_line(tl,line[i]))
        {
            return false;
        }
    }
    return true;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int flag = 0;
        tot = 0;
        if(n < 3)
            flag = 1;
        for(int i = 0; i < n; i++)
        {
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            po[tot++] = Point(x1,y1);
            po[tot++] = Point(x2,y2);
            line[i] = Line(po[tot-1],po[tot-2]);
        }
        for(int i = 0; i < tot && !flag; i++)
        {
            for(int j = i+1; !flag && j < tot; j++)
            {
                if(po[i].x == po[j].x && po[i].y == po[j].y)
                    continue;
                if(cal(Line(po[i],po[j])))
                {
                    flag = 1;
                    break;
                }
            }
        }
        if(flag)
            printf("Yes!\n");
        else
            printf("No!\n");
    }
    return 0;
}

  

时间: 2024-08-05 07:07:10

poj 3304 直线与线段相交的相关文章

POJ 1039 直线和线段相交

题意: 题意很好理解,从左边射过来的光线,最远能经过管道到右边多少距离. 分析: 光线一定经过一个上端点和一个下端点,这一点很容易想到.然后枚举上下端点即可 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define eps 1e-8 #define INF 1e9 #define OK sgn(tmp

hdu 3304(直线与线段相交)

Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12042   Accepted: 3808 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

[poj] 3304 Segments || 判断线段相交

原题 给出n条线段,判断是否有一条直线与所有线段都有交点 若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件. 每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点. 判断交点: 判断AB和CD是否相交,即判断AC×BD(叉积)和AD×BC(叉积)是否同号 #include<cstdio> #define eps 1e-13 #define N 110 using namespace std; int t,n; struct point { double x

POJ 3304 Segments(计算几何:直线与线段相交)

POJ 3304 Segments 大意:给你一些线段,找出一条直线能够穿过所有的线段,相交包括端点. 思路:遍历所有的端点,取两个点形成直线,判断直线是否与所有线段相交,如果存在这样的直线,输出Yes,但是注意去重. struct Point { double x, y; } P[210]; struct Line { Point a, b; } L[110]; double xmult(Point p1, Point p2, Point p) { return (p1.x-p.x)*(p2.

直线与直线相交 直线与线段相交 线段与线段相交

int sgn(double x) { if(fabs(x) < eps) return 0; return x < 0 ? -1:1; } struct Point { double x,y; Point() {} Point(double _x,double _y) { x = _x,y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } //叉积 double opera

POJ 1410 Intersection(线段相交&amp;&amp;判断点在矩形内&amp;&amp;坑爹)

Intersection 大意:给你一条线段,给你一个矩形,问是否相交. 相交:线段完全在矩形内部算相交:线段与矩形任意一条边不规范相交算相交. 思路:知道具体的相交规则之后题其实是不难的,但是还有个坑点就是题目里明明说给的是矩形左上角跟右下角的点,但实际上不是,需要重新判断一下...真坑. 1 struct Point 2 { 3 double x, y; 4 } A, B, C, D; 5 struct Line 6 { 7 Point a, b; 8 } L; 9 10 int n; 11

POJ 1410 Intersection(线段相交&amp;amp;&amp;amp;推断点在矩形内&amp;amp;&amp;amp;坑爹)

Intersection 大意:给你一条线段,给你一个矩形,问是否相交. 相交:线段全然在矩形内部算相交:线段与矩形随意一条边不规范相交算相交. 思路:知道详细的相交规则之后题事实上是不难的,可是还有个坑点就是题目里明明说给的是矩形左上角跟右下角的点,但实际上不是,须要又一次推断一下...真坑. struct Point { double x, y; } A, B, C, D; struct Line { Point a, b; } L; int n; double xmult(Point p1

POJ 3304 Segments 判断直线和线段相交

POJ 3304  Segments 题意:给定n(n<=100)条线段,问你是否存在这样的一条直线,使得所有线段投影下去后,至少都有一个交点. 思路:对于投影在所求直线上面的相交阴影,我们可以在那里作一条线,那么这条线就和所有线段都至少有一个交点,所以如果有一条直线和所有线段都有交点的话,那么就一定有解. 怎么确定有没直线和所有线段都相交?怎么枚举这样的直线?思路就是固定两个点,这两个点在所有线段上任意取就可以,然后以这两个点作为直线,去判断其他线段即可.为什么呢?因为如果有直线和所有线段都相

POJ 3304 Segments[直线与线段相交]

Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13514   Accepted: 4331 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