zoukankan      html  css  js  c++  java
  • POJ 2653 Pick-up sticks <<判断线段交

    题意

    求与上方的线段都没有交集的线段

    思路

    暴力判断线段交即可。

    判断线段交的方法:

    1.快速排斥实验

    如图,如果两条线段不相交,他们所组成的矩形也不相交,而判断矩形相交是很方便的,用这个方法可以快速筛掉一些线段。

    当然这并不是充要条件,两矩形相交也可能线段不相交。

    所以矩形不相交是线段不相交的充分非必要条件。

    2.那么正常的判断线段交方法:向量叉积,也就是跨立实验

    线段相交,也就是说线段$P_1P_2$跨过了线段$Q_1Q_2$,同样,$Q_1Q_2$跨过了$P_1P_2$,所以有$(overrightarrow{P_1P_2} imesoverrightarrow{P_1Q_1})cdot (overrightarrow{P_1P_2} imesoverrightarrow{P_1Q_2})<=0$使得$Q_1Q_2$跨过了$P_1P_2$

    同理,有$(overrightarrow{Q_1Q_2} imesoverrightarrow{Q_1P_1})cdot (overrightarrow{Q_1Q_2} imesoverrightarrow{Q_1P_2})<=0$使得$P_1P_2$跨过了$Q_1Q_2$

    代码

     1 #include<algorithm>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=1e5+7;
     5 const double eps=1e-8;
     6 struct Point{
     7     double x,y;
     8 };
     9 struct Segment{
    10     Point a,b;
    11 }seg[maxn];
    12 double cross(Point p,Point a,Point b)
    13 {
    14     //cout<<p.x<<","<<p.y<<";"<<a.x<<","<<a.y<<";"<<b.x<<","<<b.y<<endl;
    15     Point pa={a.x-p.x,a.y-p.y};
    16     Point pb={b.x-p.x,b.y-p.y};
    17     double ret=pa.x*pb.y-pa.y*pb.x;
    18     //cout<<ret<<endl;
    19     return ret;
    20 }
    21 bool intersect(Segment l1,Segment l2)
    22 {
    23     return 
    24         max(l1.a.x,l1.b.x) >= min(l2.a.x,l2.b.x) &&
    25         max(l2.a.x,l2.b.x) >= min(l1.a.x,l1.b.x) &&
    26         max(l1.a.y,l1.b.y) >= min(l2.a.y,l2.b.y) &&
    27         max(l2.a.y,l2.b.y) >= min(l1.a.y,l1.b.y) &&
    28         cross(l1.a,l2.a,l1.b)*cross(l1.a,l2.b,l1.b) <= 0 &&
    29         cross(l2.a,l1.a,l2.b)*cross(l2.a,l1.b,l2.b) <= 0;
    30 }
    31 int main()
    32 {
    33     int n;
    34     while(~scanf("%d",&n)&&n)
    35     {
    36         for(int i=0;i<n;i++)
    37         {
    38             scanf("%lf%lf%lf%lf",&seg[i].a.x,&seg[i].a.y,&seg[i].b.x,&seg[i].b.y);
    39         }
    40         printf("Top sticks:");
    41         for(int i=0;i<n-1;i++)
    42         {
    43             for(int j=i+1;j<n;j++)
    44             {
    45                 if(intersect(seg[i],seg[j]))
    46                     goto next;
    47             }
    48             printf(" %d,",i+1);
    49             next:;
    50         }
    51         printf(" %d.
    ",n);
    52 
    53     }
    54 }
  • 相关阅读:
    JAVA_WEB--jsp概述
    npr_news英语新闻听力——每日更新
    词根词缀高效背单词技巧--词霸天下完整版
    python刷LeetCode:1071. 字符串的最大公因子
    python刷LeetCode:1013. 将数组分成和相等的三个部分
    python刷LeetCode:543. 二叉树的直径
    python刷LeetCode:121. 买卖股票的最佳时机
    python刷LeetCode:38. 外观数列
    python刷LeetCode:35. 搜索插入位置
    python刷LeetCode:28. 实现 strStr()
  • 原文地址:https://www.cnblogs.com/computer-luo/p/10081794.html
Copyright © 2011-2022 走看看