首页 > 其他 > 详细

ACM-计算几何之Segments——poj3304

时间:2014-04-16 11:34:22      阅读:561      评论:0      收藏:0      [点我收藏+]
Segments

题目:http://poj.org/problem?id=3304

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 (x1, y1) and (x2, y2) 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!


求是否存在一条直线可以与列出的所有线段相交。

解题:如果存在这么一条直线,必定过平面中的两个点,

所以任意穷举两个点所在的直线与所有线段判断是否相交。

这道题还有注意精度问题。


#include <iostream>
#define MAX 201
using namespace std;

int n;
// 精度判定
const double eps = 1E-8;
int sig(double d)
{
    return (d>eps) - (d<-eps);
}
struct Point
{
    double x,y;

}point[MAX];

double cross(Point &o,Point& a,Point &b)
{
    return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
}

//判断直线ab是否与线段cd相交
//0 不相交
//1 规范相交
//2 不规范相交
int segLineCross(Point &a,Point &b,Point &c,Point &d)
{
    int d1,d2;
    d1 = sig(cross(a,b,c));
    d2 = sig(cross(a,b,d));
    if((d1^d2)==-2)//注意加小括号,^的优先级比==低
        return 1;
    if(d1==0 || d2==0)
        return 2;
    return 0;
}

bool Test(Point &a,Point &b)//判断直线ab是否与所有线段相交
{
    int i;
    if(sig(a.x-b.x)==0 && sig(a.y-b.y)==0)//★判断重复点
        return false;
    for(i=0;i<2*n;i+=2)
        if(segLineCross(a,b,point[i],point[i+1])==0)
            return false;
    return true;
}

bool Find()
{
    int i,j;
    for(i=0;i<2*n;++i)
        for(j=0;j<2*n;++j)
            if(Test(point[i],point[j]))
                return true;
    return false;
}
int main()
{
    int test,i;
    cin >> test;
    while(test--)
    {
        cin >> n;
        for(i=0;i<2*n;++i)
            cin>>point[i].x>>point[i].y;

        if(Find())
            cout << "Yes!" << endl;
        else
            cout << "No!" << endl;
    }
    return 0;
}



ACM-计算几何之Segments——poj3304,布布扣,bubuko.com

ACM-计算几何之Segments——poj3304

原文:http://blog.csdn.net/lttree/article/details/23788215

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!