zoukankan      html  css  js  c++  java
  • POJ3304 Segments 【线段直线相交】

    题意:

    给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。

    思路:

    计算几何。这道题要思考到两点:

    1:把问题转化为是否存在一条直线与每条线段都有交点。证明:若存在一条直线l和所有线段相交,作一条直线m和l垂直,则m就是题中要求的直线,所有线段投影的一个公共点即为垂足。

    2:枚举两两线段的各一个端点,连一条直线,再判断剩下的线段是否都和这条直线有交点。证明:若有l和所有线段相交,则可保持l和所有线段相交,左右平移l到和某一线段交于端点停止(“移不动了”)。然后绕这个交点旋转。也是转到“转不动了”(和另一线段交于其一个端点)为止。这样就找到了一个新的l满足题意,而且经过其中两线段的端点。

    判断线段与直线l是否相交的方法:

    1:利用叉积的性质,判断线段的两个端点是否在直线的两边。

    2:求线段所在的直线tmp,求tmp与l的交点p,由线段两端点到p的距离之和,与线段的距离比较,若相等则证明线段与直线相交。

    代码:

    #include<iostream>
    #include<cmath>
    using namespace std;
    const int maxn = 105;
    const double eps = 1e-8;
    int n;
    
    struct Point
    {
        double x, y;
    }s[maxn], e[maxn];
    
    double mult(Point sp, Point ep, Point op)
    {
        return (sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y);
    }
    
    bool findd(Point p1, Point p2)
    {
        if(abs(p1.x-p2.x) < eps && abs(p1.y-p2.y) < eps)
            return false;
        for(int i = 0; i < n; i ++)
            if(mult(p1, p2, s[i])*mult(p1, p2, e[i]) > eps) return false;
        return true;
    }
    
    int main()
    {
        int t, i, j;
        cin >> t;
        while(t --)
        {
            cin >> n;
            for(i = 0; i < n; i ++)
                cin >> s[i].x >> s[i].y >> e[i].x >> e[i].y;
            bool flag = false;
            if(n < 3) flag = true;
            for(i = 0; i < n && !flag; i ++)
                for(j = i + 1; j < n && !flag; j ++)    //  枚举线段的端点。
                {
                    if(findd(s[i], s[j])) flag = true;
                    else if(findd(s[i], e[j])) flag = true;
                    else if(findd(e[i], s[j])) flag = true;
                    else if(findd(e[i], e[j])) flag = true;
                }
               if(flag) cout << "Yes!" << endl;
               else cout << "No!" << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/darklights/p/7640426.html
Copyright © 2011-2022 走看看