[백준 / BOJ][Python] 2162 - 선분 그룹
2023. 3. 1. 04:53ㆍProblem Solving
[백준 / BOJ][Python] 2162 - 선분 그룹
https://www.acmicpc.net/problem/2162
2162번: 선분 그룹
첫째 줄에 N(1 ≤ N ≤ 3,000)이 주어진다. 둘째 줄부터 N+1번째 줄에는 양 끝점의 좌표가 x1, y1, x2, y2의 순서로 주어진다. 각 좌표의 절댓값은 5,000을 넘지 않으며, 입력되는 좌표 사이에는 빈칸이 하
www.acmicpc.net
문제 풀이
선분 교차 판정 + 유니온 파인드 이용하는 문제. 교차하는 선분들이 있다면 같은 그룹에 속하는 선분이라는 뜻이기에 Union 작업을 실시하면 된다. N ≤ 3,000 이므로 모든 조합을 시도해도 대략 450만 정도의 수가 나온다. 즉, Naive하게 풀이를 진행하면 된다. 추가로, 모든 Union 과정이 끝난 후 각 선분들의 번호에 대해 Find를 한번씩 진행해야 한다. 그렇지 않으면 마저 갱신되지 못한 번호들이 남아있을 수 있기 때문.
코드
import sys, itertools
input = sys.stdin.readline
def ccw(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
return (x1 * y2 + x2 * y3 + x3 * y1) - (x2 * y1 + x3 * y2 + x1 * y3)
def line_intersection(p1, p2, p3, p4): #선분 교차 판정
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
x4, y4 = p4
cross1 = ccw(p1, p2, p3) * ccw(p1, p2, p4)
cross2 = ccw(p3, p4, p1) * ccw(p3, p4, p2)
if cross1 == cross2 == 0:
if min(x1, x2) <= max(x3, x4) and min(x3, x4) <= max(x1, x2) and min(y1, y2) <= max(y3, y4) and min(y3, y4) <= max(y1, y2):
return 1
elif cross1 <= 0 and cross2 <= 0:
return 1
return 0
def find(x):
if graph[x] != x:
graph[x] = find(graph[x])
return graph[x]
def union(x, y):
x = find(x)
y = find(y)
if x < y:
graph[y] = x
else:
graph[x] = y
n = int(input())
graph = [i for i in range(n + 1)] #Union Find 연산을 실행할 list
lines = [] #선분들을 저장할 list
for i in range(n):
x1, y1, x2, y2 = map(int, input().split())
lines.append([i + 1, [x1, y1], [x2, y2]]) #[번호, 시작점, 끝점]
for i in itertools.combinations(lines, 2): #가능한 모든 조합 (combination(n, 2))
a, p1, p2 = i[0]
b, p3, p4 = i[1]
if line_intersection(p1, p2, p3, p4): #두 선분이 교차한다면
union(a, b) #한 그룹으로 묶어준다.
for i in range(1, n + 1):
graph[i] = find(i) #Union 후 모든 선분 번호들에 대해 Find 갱신
num_set = list(set(graph))
num_set.remove(0)
ans = 0
for i in num_set:
ans = max(graph.count(i), ans)
print(len(num_set)) #총 그룹의 수
print(ans) #가장 많은 선분을 보유한 그룹의 선분 수
'Problem Solving' 카테고리의 다른 글
[백준 / BOJ][Python] 2170 - 선 긋기 (0) | 2023.03.08 |
---|---|
[백준 / BOJ][Python] 1185 - 유럽 여행 (0) | 2023.03.06 |
[백준 / BOJ][Python] 17387 - 선분 교차 2 (1) | 2023.03.01 |
[백준 / BOJ][Python] 17386 - 선분 교차 1 (0) | 2023.03.01 |
[백준 / BOJ][Python] 27514 - 1차원 2048 (0) | 2023.02.27 |