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
  • 相关阅读:
    SQL Server查询死锁并KILL
    android之Widget01
    android之RatingBar控件用法
    android之SeekBar控件用法
    android之ExpandableListActivity
    【原创】开源.NET排列组合组件KwCombinatorics使用(一)—组合生成
    【吐槽】博客园新的原创文章在搜索引擎的排名不及转载的站点
    【资源】108个大数据文档PDF开放下载-整理后打包下载
    【原创】.NET平台机器学习组件-Infer.NET连载(二)贝叶斯分类器
    【原创】.NET平台机器学习组件-Infer.NET连载(一)介绍
  • 原文地址:https://www.cnblogs.com/darklights/p/7640426.html
Copyright © 2011-2022 走看看