문제 바로가기
문제:
로고는 주로 교육용에 쓰이는 프로그래밍 언어이다. 로고의 가장 큰 특징은 거북이 로봇인데, 사용자는 이 거북이 로봇을 움직이는 명령을 입력해 화면에 도형을 그릴 수 있다. 거북이는 위치와 각도로 표현할 수 있다. 거북이는 입에 연필을 물고 있는데, 연필을 내리면 움직일 때 화면에 선을 그리고, 올리면 선을 그리지 않고 그냥 지나가기만 한다. 제일 처음에 거북이는 (0,0)에 있고, 거북이가 보고 있는 방향은 y축이 증가하는 방향이다. 또한 연필은 내리고 있다. 사용자는 다음과 같은 다섯가지 명령으로 거북이를 조정할 수 있다.
FD x: 거북이를 x만큼 앞으로 전진
LT a: 거북이를 반시계 방향으로 a도 만큼 회전
RT a: 거북이를 시계 방향으로 a도 만큼 회전
PU: 연필을 올린다
PD: 연필을 내린다.
축에 평행한 직사각형 N개가 주어졌을 때, 이 직사각형을 그리는데 필요한 PU 명령의 최솟값을 구하는 프로그램을 작성하시오. 거북이는 같은 선을 여러 번 그릴 수 있지만, 문제에 주어진 직사각형 N개를 제외한 어떤 것도 그릴 수 없다. 거북이의 크기는 아주 작아서 좌표 평면의 한 점이라고 생각하면 된다. 직사각형의 변은 축에 평행하다.
입력:
첫째 줄에 직사각형의 개수 N이 주어진다. (1 ≤ N ≤ 1000) 다음 N개의 줄에는 직사각형의 좌표 x1, y1, x2, y2가 주어진다. (−500 ≤ x1 < x2 ≤ 500), (−500 ≤ y1 < y2 ≤ 500) (x1, y1)는 직사각형의 한 꼭짓점 좌표이고, (x2, y2)는 그 점의 대각선 방향의 반대 꼭짓점의 좌표이다.
출력:
N개의 직사각형을 그리는 필요한 PU명령의 최솟값을 출력한다.
풀이:
분리집합 문제이다.
두 직사각형이 하나라도 선이 지나치게 되면 한 번에 그릴수 있다.
하지만 한 직사각형이 다른 직사각형 안에 들어가있으면 한 번에 못 그리고 한 번 PU 가 필요하다.
union-find 를 사용해 풀었다.
import sys
sys.stdin = open('/Users/song/Desktop/Python/Python/h.txt', 'r')
# 겹치는지 확인하는 함수
def is_overlapping(x1_1, y1_1, x2_1, y2_1, x1_2, y1_2, x2_2, y2_2):
# 한 직사각형이 다른 직사각형을 완전히 포함하는 경우 겹치지 않는 것으로 간주
if (x1_1 < x1_2 and y1_1 < y1_2 and x2_1 > x2_2 and y2_1 > y2_2) or \
(x1_2 < x1_1 and y1_2 < y1_1 and x2_2 > x2_1 and y2_2 > y2_1):
return False
# 기본 겹침 여부 확인
if x2_1 < x1_2 or x1_1 > x2_2 or y2_1 < y1_2 or y1_1 > y2_2:
return False
else:
return True
n = int(input())
graph = [[] for _ in range(n)]
rectangles = [list(map(int, sys.stdin.readline().rstrip().split())) for _ in range(n)]
parent = [i for i in range(n)]
start_zero = False
# 0,0 에서 갈 수 있는거 찾음
for rectangle in rectangles:
a, b, c, d = rectangle
if a == 0 or c == 0:
if b <= 0 <= d:
start_zero = True
elif b == 0 and d == 0:
if a <= 0 <= c:
start_zero = True
def find(i):
if i != parent[i]:
parent[i] = find(parent[i])
return parent[i]
def union(a, b):
aa = find(a)
bb = find(b)
if aa < bb:
parent[bb] = aa
else:
parent[aa] = bb
for i in range(n - 1):
for j in range(i + 1, n):
if is_overlapping(*rectangles[i], *rectangles[j]):
# 몇 번 째 사각형끼리 union인지
union(i, j)
cnt = 0
for i in range(n):
if parent[i] == i:
cnt += 1
if start_zero:
cnt -= 1
print(cnt)
첫 start_zero가 문제였다.
(0.0) 에서 시작 하기 때문에 직사각형이 (0.0) 을 지나가는지 체크해줘야한다.
댓글