https://www.acmicpc.net/problem/3108
시간 1초, 메모리 128MB
input :
output :
조건 :
PU의 커맨드를 몇 번 이용하는 가에 대한 물음으로.
예제를 그려보면 어떤 직사각형들의 변이 만나는 것을 볼 수 있다. 이럴 경우엔 거북이가 계속 그림을 그리기 때문에 다른 커맨드가 필요없다.
내가 집중해야 하는 부분은 연필을 언제 올리는 지에 관한 것이다.
한 덩어리의 직사각형의 개수 만큼 연필을 들어올리는 횟수가 되기 때문에 BFS로 직사각형이 몇 개 나 있는지 확인을 해야 한다.
그런데 직사각형 사이의 거리가 1이면 이는 BFS로 탐색을 해버리기 때문에 인위적으로 거리를 더 넓혀야 한다.
그래서 입력이 가능한 범위가 -500 에서 500이기 때문에. 500을 더해 (0 <= 입력 <= 1000) 으로 만들어 주고.
거리를 2배로 늘려야 하니 2를 곱해 주자.
x1 = 2 * (500 + item[0])
y1 = 2 * (500 + item[1])
x2 = 2 * (500 + item[2])
y2 = 2 * (500 + item[3])
작은 사각형들 중에 큰 직사각형의 변에 닿지는 않고 그 안에 존재 할 가능 성도 있기 때문에, 직사각형의 내부는 비어 있어야 한다.
이를 위해. x의 좌표가 x1, x2가 아닌 경우에는 양 끝 변만 1로 바꿔준다.
for nx in range(x1, x2 + 1):
if nx == x1 or nx == x2:
for ny in range(y1, y2 + 1):
graph[nx][ny] = 1
else:
graph[nx][y1] = 1
graph[nx][y2] = 1
그리고 시작하는 지점이 (0, 0)일 경우에는 펜이 이미 내려가 있기 때문에 -1 부터 시작하자.
if graph[1000][1000] == 1:
cnt = -1
else:
cnt = 0
정답 코드 :
import sys
from _collections import deque
n = int(sys.stdin.readline())
rectangle = []
for i in range(n):
rectangle.append(list(map(int, sys.stdin.readline().split())))
graph = [[0] * 2001 for i in range(2001)]
position = []
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
# 0, 0 은 1000, 1000
for item in rectangle:
x1 = 2 * (500 + item[0])
y1 = 2 * (500 + item[1])
x2 = 2 * (500 + item[2])
y2 = 2 * (500 + item[3])
position.append((x1, y1))
for nx in range(x1, x2 + 1):
if nx == x1 or nx == x2:
for ny in range(y1, y2 + 1):
graph[nx][ny] = 1
else:
graph[nx][y1] = 1
graph[nx][y2] = 1
def bfs(x, y):
q = deque([])
q.append((x, y))
graph[x][y] = 0
while q:
now_x, now_y = q.popleft()
for i in range(4):
nx = now_x + dx[i]
ny = now_y + dy[i]
if nx > 2000 or nx < 0 or ny > 2000 or ny < 0:
continue
if graph[nx][ny] == 1:
graph[nx][ny] = 0
q.append((nx, ny))
if graph[1000][1000] == 1:
cnt = -1
else:
cnt = 0
for x, y in position:
if graph[x][y] == 1:
cnt += 1
bfs(x, y)
print(cnt)