Jack Straws —— 判断直线相交

传送门Poj1127

描述

In the game of Jack Straws, a number of plastic or wooden “straws” are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are connected by a path of touching straws. You will be given a list of the endpoints for some straws (as if they were dumped on a large piece of graph paper) and then will be asked if various pairs of straws are connected. Note that touching is connecting, but also two straws can be connected indirectly via other connected straws.

输入

A problem consists of multiple lines of input. The first line will be an integer n (1 < n < 13) giving the number of straws on the table. Each of the next n lines contain 4 positive integers, x1 , y1 , x2 and y2 , giving the coordinates, (x1 ; y1 ); (x2 ; y2 ) of the endpoints of a single straw. All coordinates will be less than 100. (Note that the straws will be of varying lengths.) The first straw entered will be known as straw #1, the second as straw #2, and so on. The remaining lines of input (except for the final line) will each contain two positive integers, a and b, both between 1 and n, inclusive. You are to determine if straw a can be connected to straw b. When a = 0 = b, the input is terminated. There will be no illegal input and there are no zero-length straws.

输出

You should generate a line of output for each line containing a pair a and b, except the final line where a = 0 = b. The line should say simply “CONNECTED”, if straw a is connected to straw b, or “NOT CONNECTED”, if straw a is not connected to straw b. For our purposes, a straw is considered connected to itself.

样例

  • Input
    7
    1 6 3 3
    4 6 4 9
    4 5 6 7
    1 4 3 5
    3 5 5 5
    5 2 6 3
    5 4 7 2
    1 4
    1 6
    3 3
    6 7
    2 3
    1 3
    0 0
    2
    0 2 0 0
    0 0 0 1
    1 1
    2 2
    1 2
    0 0

0

  • Output
    CONNECTED
    NOT CONNECTED
    CONNECTED
    CONNECTED
    NOT CONNECTED
    CONNECTED
    CONNECTED
    CONNECTED
    CONNECTED

题解

  • 题意:给出n条线段的起点和终点,线段相交具有传递性,询问某两条线间是否连通
  • 快速排斥实验+跨立实验判定两线段相交,Floyd预处理联通性,O(1)查询

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<bits/stdc++.h>
#define INIT(a,b) memset(a,b,sizeof(a))
const int maxn=1e2+7;
const int inf=0x3f3f3f3f;
using namespace std;
struct Edge{
int x1,y1,x2,y2;
}edge[maxn];
bool judge(Edge l1, Edge l2){
//快速排斥实验
if ((l1.x1 > l1.x2 ? l1.x1 : l1.x2) < (l2.x1 < l2.x2 ? l2.x1 : l2.x2) ||
(l1.y1 > l1.y2 ? l1.y1 : l1.y2) < (l2.y1 < l2.y2 ? l2.y1 : l2.y2) ||
(l2.x1 > l2.x2 ? l2.x1 : l2.x2) < (l1.x1 < l1.x2 ? l1.x1 : l1.x2) ||
(l2.y1 > l2.y2 ? l2.y1 : l2.y2) < (l1.y1 < l1.y2 ? l1.y1 : l1.y2)){
return false;
}
//跨立实验
if ((((l1.x1 - l2.x1)*(l2.y2 - l2.y1) - (l1.y1 - l2.y1)*(l2.x2 - l2.x1))*
((l1.x2 - l2.x1)*(l2.y2 - l2.y1) - (l1.y2 - l2.y1)*(l2.x2 - l2.x1))) > 0 ||
(((l2.x1 - l1.x1)*(l1.y2 - l1.y1) - (l2.y1 - l1.y1)*(l1.x2 - l1.x1))*
((l2.x2 - l1.x1)*(l1.y2 - l1.y1) - (l2.y2 - l1.y1)*(l1.x2 - l1.x1))) > 0){
return false;
}
return true;
}
int con[20][20];
int main() {
int n,a,b,c,d;
while(~scanf("%d",&n)){
INIT(con,0);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
edge[i]=(Edge){a,b,c,d};
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(judge(edge[i],edge[j]))
con[i][j]=1;

for(int i=1;i<=n;i++)
for(int k=1;k<=n;k++)
for(int j=1;j<=n;j++)
if(con[i][k] && con[k][j])
con[i][j]=con[j][i]=1;

while(~scanf("%d%d",&a,&b)&&(a||b)){
if(con[a][b]||con[b][a]) printf("CONNECTED\n");
else printf("NOT CONNECTED\n");
}
}


return 0;
}
Donate comment here