반응형
2차원 평면상에 선분들이 주어질 때, 두 선분이 만나면 같은 그룹이라 한다. 이때 가장 큰 그룹에 속한 선분의 개수를 구하는 문제이다.
그룹핑하기 위해 Union Find를 사용했고, CCW로 선분의 교차 유무를 판별하였다.
코드는 다음과 같다.
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#include <cstring>
#include <cstdio>
int par[3001];
int L[3001][4];
int maxx(int a, int b) {
return a > b ? a : b;
}
int minn(int a, int b) {
return a < b ? a : b;
}
int CCW(double x1, double y1, double x2, double y2, double x3, double y3) {
double tmp = x1 * y2 + x2 * y3 + x3 * y1;
tmp -= (y1 * x2 + y2 * x3 + y3 * x1);
if (tmp < 0)
return -1;
if (tmp > 0)
return 1;
return 0;
}
int find(int i) {
if (par[i] < 0)
return i;
return par[i] = find(par[i]);
}
void Union(int i, int j) {
int p = find(i);
int q = find(j);
if (p == q)
return;
par[p] += par[q];
par[q] = p;
}
bool isoverlapped(double l1x1, double l1y1, double l1x2, double l1y2, double l2x1, double l2y1, double l2x2, double l2y2) {
if (maxx(l1x1, l1x2) < minn(l2x1, l2x2))
return false;
if (minn(l1x1, l1x2) > maxx(l2x1, l2x2))
return false;
if (maxx(l1y1, l1y2) < minn(l2y1, l2y2))
return false;
if (minn(l1y1, l1y2) > maxx(l2y1, l2y2))
return false;
return true;
}
bool iscrossed(double l1x1, double l1y1, double l1x2, double l1y2, double l2x1, double l2y1, double l2x2, double l2y2) {
double chk1 = CCW(l1x1, l1y1, l1x2, l1y2, l2x1, l2y1)*CCW(l1x1, l1y1, l1x2, l1y2, l2x2, l2y2);
double chk2 = CCW(l2x1, l2y1, l2x2, l2y2, l1x1, l1y1)*CCW(l2x1, l2y1, l2x2, l2y2, l1x2, l1y2);
if (chk1 == 0 && chk2 == 0) {
return isoverlapped(l1x1, l1y1, l1x2, l1y2, l2x1, l2y1, l2x2, l2y2);
}
return chk1 <= 0 && chk2 <= 0;
}
int main()
{
register int i, j;
int N;
scanf("%d", &N);
for (i = 1; i <= N; i++) {
par[i] = -1;
}
for (i = 1; i <= N; i++) {
scanf("%d %d %d %d", &L[i][0], &L[i][1], &L[i][2], &L[i][3]);
for (j = 1; j < i; j++) {
if (iscrossed(L[i][0], L[i][1], L[i][2], L[i][3], L[j][0], L[j][1], L[j][2], L[j][3]) == true) {
Union(i, j);
}
}
}
int ans = 0, res=0;
for (i = 1; i <= N; i++) {
if (par[i] < 0) {
ans++;
res = minn(res, par[i]);
}
}
printf("%d\n", ans);
printf("%d\n", -res);
return 0;
}
|
cs |
반응형
'Algorithm > Computational Geometry' 카테고리의 다른 글
BOJ 1485: 정사각형 (0) | 2019.02.21 |
---|---|
BOJ 6439번: 교차 (0) | 2019.02.21 |