一 题面

  POJ1127

二 分析

  在平面几何中,判断两线段相交的方法一般是使用跨立实验。但是这题考虑了非严格相交,即如何两个线段刚好端点相交则也是相交的,所以还需要使用快速排斥实验。

  这里参考并引用了TangMoon 博客。

  1.快速排斥实验

  由于两个点作为矩形的两个斜对角线端点可以确定一个矩形,则根据两个点确定一个向量,两个向量显然可以确定两个矩形。

  对于快速排斥实验,也可尝试逆向思维,如果判断让两个向量确定的两个矩形是否相交部分,相当于判断两个矩形没有相交部分的反。

  具体条件就是a.其中一个矩形的最小横坐标大于另一个矩形的最大横坐标;b.其中一个矩形的最小纵坐标大于另一个矩形的最大纵坐标。

  2.跨立实验

  

  如图,根据以$Q1$为起点

${\overrightarrow{Q_{1}P_{2}} }\times {\overrightarrow{Q_{1}Q_{2}}}$

${\overrightarrow{Q_{1}Q_{2}} }\times {\overrightarrow{Q_{1}P_{1}}}$

  判断这两个向量的正负,如果两个值正负相同,表示$\overrightarrow{Q_{1}Q_{2}}$在两向量中间,但这显然还不够,因为可能$Q2$没跨过去,所以还需要在$P1$判断一次。

  

  那么这样把上述两条件都判断后,就能保证两线段非严格相交了。

三 AC代码

  1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4
5 using namespace std;
6 const int MAXN = 200;
7 struct P
8 {
9 int a, b;
10 P(){}
11 P(int x, int y): a(x),b(y){}
12 P operator + (P t)
13 {
14 return P(a + t.a, b + t.b);
15 }
16 P operator - (P t)
17 {
18 return P(a - t.a, b - t.b);
19 }
20 P operator * (P t)
21 {
22 return P(a*t.a, b*t.b);
23 }
24 int dot(P t)
25 {
26 return a*t.a + b*t.b;
27 }
28 int det(P t)
29 {
30 return a*t.b - b*t.a;
31 }
32 };
33 int px[MAXN], py[MAXN];
34 int qx[MAXN], qy[MAXN];
35
36 bool solve(int t1, int t2)
37 {
38 if(min(px[t1], qx[t1]) > max(px[t2], qx[t2]) || min(px[t2], qx[t2]) > max(px[t1], qx[t1])
39 || min(py[t1], qy[t2]) > max(py[t2], qy[t2]) || min(py[t2], qy[t2]) > max(py[t1], qy[t1]))
40 return false;
41 P p1, p2, p3;
42 p1 = P(qx[t1]-px[t2], qy[t1]-py[t2]);
43 p2 = P(qx[t2]-px[t2], qy[t2]-py[t2]);
44 p3 = P(px[t1]-px[t2], py[t1]-py[t2]);
45 if(p1.det(p2) * p2.det(p3) < 0)
46 return false;
47 p1 = P(px[t2]-px[t1], py[t2]-py[t1]);
48 p2 = P(qx[t1]-px[t1], qy[t1]-py[t1]);
49 p3 = P(qx[t2]-px[t1], qy[t2]-py[t1]);
50 if(p1.det(p2) * p2.det(p3) < 0)
51 return false;
52 return true;
53 }
54
55 int par[MAXN];
56
57 int find(int x)
58 {
59 return par[x] == x ? x : par[x] = find(par[x]);
60 }
61 void unite(int x, int y)
62 {
63 int f1 = find(x), f2 = find(y);
64 if(f1 == f2)
65 return;
66 else
67 par[f1] = f2;
68 }
69
70
71 int main()
72 {
73 //freopen("input.txt", "r", stdin);
74 int n;
75 while(scanf("%d", &n) == 1)
76 {
77
78 if(n == 0) break;
79 for(int i = 1; i <= n; i++)
80 {
81 par[i] = i;
82 scanf("%d%d%d%d", &px[i], &py[i], &qx[i], &qy[i]);
83 }
84 for(int i = 1; i <= n; i++)
85 for(int j = i + 1; j <= n; j++)
86 {
87 if(solve(i, j))
88 unite(i, j);
89 }
90 int x, y;
91 while(scanf("%d%d", &x, &y) != EOF)
92 {
93 if(x == 0) break;
94 if(find(x) == find(y))
95 printf("CONNECTED\n");
96 else
97 printf("NOT CONNECTED\n");
98 }
99 }
100 return 0;
101 }

POJ_1227 Jack Straws 【二维平面判两线段相交】的更多相关文章

  1. Jack Straws(poj 1127) 两直线是否相交模板

    http://poj.org/problem?id=1127   Description In the game of Jack Straws, a number of plastic or wood ...

  2. poj 1127:Jack Straws(判断两线段相交 + 并查集)

    Jack Straws Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2911   Accepted: 1322 Descr ...

  3. You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3276 ...

  4. hdu 1147:Pick-up sticks(基本题,判断两线段相交)

    Pick-up sticks Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  5. poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

    Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...

  6. TOJ1840: Jack Straws 判断两线段相交+并查集

    1840: Jack Straws  Time Limit(Common/Java):1000MS/10000MS     Memory Limit:65536KByteTotal Submit: 1 ...

  7. hdu 1086:You can Solve a Geometry Problem too(计算几何,判断两线段相交,水题)

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  8. ACM1558两线段相交判断和并查集

    Segment set Problem Description A segment and all segments which are connected with it compose a seg ...

  9. HDU 1147 /// 判断两线段相交

    题目大意: 给定n条线段的端点 依次放上n条线段 判断最后在最上面(不被覆盖)的线段有哪些 到当前线段后 直接与之前保存的未被覆盖的线段判断是否相交就可以了 #include <cstdio&g ...

随机推荐

  1. tensorflow-gpu+"Failed to create session"

    成因: 未给系统指定相应使用的GPU 解决: 层面1: 针对单个程序: CUDA_VISIBLE_DEVICES=0 python main.py import os; os.environ['CUD ...

  2. 读写 LED 作业 台灯的 频闪研究1

    读写 LED 作业 台灯的 频闪研究: 核心提示: 随着科技的持续发展,目前已经商业化的照明产品从第一代的白炽灯: 第二代的荧光灯.卤灯: 第三代的高强度气体放电灯; 以及当下主流的, 第四代的发光二 ...

  3. virtual whiteboard

    virtual whiteboard 虚拟白板 / canvas https://twitter.com/excalidraw https://excalidraw.com/ https://gith ...

  4. 如何通过 terminal 查看一个文件的 meta信息

    如何通过 terminal 查看一个文件的 meta 信息 Linux shell stat 查看文件 meta 信息 stat stat指令:文件/文件系统的详细信息显示: 使用格式:stat 文件 ...

  5. Google Advanced Search Skills

    Google Advanced Search Skills site:

  6. 比特币跌破3.5万美元,巨鲸们将目光瞄向SPC算力币

    比特币最近又迎来了大幅下跌,截至周三(1月20日),比特币跌幅超过5%,跌破3.5万美元.很显然,比特币没有预期那样顺顺利利地登顶4万美元,反而又出现了回调迹象.有些巨鲸们在大肆囤币,然而也有些巨鲸们 ...

  7. 人物传记JULLIAN MURPHY:投资哪家强,区块链必然>股票+房地产

    今年上半年在金融股市出现巨大波动的时候,星盟的项目审核经理JULLIAN MURPHY发现了一个有趣的现象:各种熔断和暴跌的背后,特斯拉的股票却从去年年末开始至今已经暴涨了12倍,即便中途有所回落,但 ...

  8. django学习-2.urls.py和view.py的相关知识点

    1.URL函数简单解析 1.1.url() 函数可以接收四个参数,分别是两个必选参数:regex.view,和两个可选参数:kwargs.name. def url(regex, view, kwar ...

  9. pytorch resnet实现

    官方github上已经有了pytorch基础模型的实现,链接 但是其中一些模型,尤其是resnet,都是用函数生成的各个层,自己看起来是真的难受! 所以自己按照caffe的样子,写一个pytorch的 ...

  10. InnoDB 的记录结构和页结构

    本文转载自InnoDB 的记录结构和页结构 概述 InnoDB将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,中页的大小一般为16KB.也就是在一般情况下,一次最少从磁盘中读取16KB的内 ...