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.y-p.y)-(p1.y-p.y)*(p2.x-p.x);
}

bool segLineInter(Line seg, Line line)
{
    double d1, d2;
    d1 = xmult(seg.a, line.a, line.b);
    d2 = xmult(seg.b, line.a, line.b);
    if((d1>eps && d2 < -eps) || (d1 < -eps && d2 > eps))
        return true;
    if(fabs(d1) < eps || fabs(d2) < eps)
        return true;
    return false;
}

int T;
int n;

void Solve()
{
    Line l1, l2;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        int t = 0;
        for(int i = 0; i < n; ++i)
        {
            scanf("%lf%lf%lf%lf", &L[i].a.x, &L[i].a.y, &L[i].b.x, &L[i].b.y);
            P[t++] = L[i].a;
            P[t++] = L[i].b;
        }
        bool ans = false;
        for(int i = 0; !ans && i < t; ++i)
        {
            for(int j = i+1; j < t; ++j)
            {
                bool flag = true;
                if(fabs(P[i].x-P[j].x) < eps && fabs(P[i].y-P[j].y) < eps) continue;
                for(int k = 0; k < n; ++k)
                {
                    if(segLineInter(L[k], (Line){P[i], P[j]}) == false)
                    {
                        flag = false;
                        break;
                    }
                }
                if(flag == true)
                {
                    ans = true;
                    break;
                }
            }
        }
        printf("%s!\n", ans?"Yes":"No");
    }
}

POJ 3304 Segments(计算几何:直线与线段相交),布布扣,bubuko.com

时间: 2024-10-13 00:59:12

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

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

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

POJ 3304 Segments (直线与线段是否相交)

题目链接 题意 : 能否找出一条直线使得所有给定的线段在该直线上的投影有一个公共点. 思路 : 假设存在一条直线a使得所有线段在该直线上的投影有公共点,则必存在一条垂直于直线a的直线b,直线b与所有线段相交,所以问题又转变为是否存在一条直线与所在所有线段相交. 假设这样的直线存在,则这一条直线可能与某一条或者某些线段的端点重合,也可能不重合.对于那些没有在端点相交的线段,我们可以把这一条直线通过旋转或平移,让其先与一条线段在线段的端点相交(那此时这一条直线与别的线段就在别的线段的中间相交), 然

POJ 3304 Segments(计算几何)

题意:给定一些线段,问能否找出一条直线,穿过所有线段 思路:如果存在一条直线,那么必然有一条直线是过已有的两点,那么就枚举两点,然后去判断是否跟所有线段有交点即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; struct Point { double x, y; Point() {} Point(doub

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

POJ 3304 Segments 线段和直线的交点

C - Segments Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3304 Appoint description:  System Crawler  (2016-05-07) Description Given n segments in the two dimensional space, write a program, w

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 1039 直线和线段相交

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

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

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 3304 Segments【叉积】

题意:有n条线段,问有没有一条直线使得所有线段在这条直线上的投影至少有一个共同点. 思路:逆向思维,很明显这个问题可以转化为是否有一条直线穿过所有线段,若有,问题要求的直线与该直线垂直,并且公共点为垂足. 因此只需要枚举每两个端点形成的直线,判断是否和所有线段相交.证明,若存在一条与所有线段相交的直线L,则可以将L平移直到再移动就不满足"与所有线段相交"这个条件时,此时L经过某个线段的一个端点,再将L旋转直到再旋转就不满足“与所有线段相交"这个条件时,肯定与另一个端点相交.