백준 1780 - 종이의 개수 (Python3)
코드
n = int(input())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
# -1, 0, 1로만 채워진 종이의 개수를 담을 리스트
cnt_list = [0, 0, 0]
# 메소드 구현
def solution(x, y, n):
color = graph[x][y]
# N의 범위가 3의 7승(2187)이므로
# 그리 크지 않음 => 4중 포문으로 시간내 구현 가능
for i in range(x, x+n):
for j in range(y, y+n):
if color != graph[i][j]:
# 9개의 종이로 자름 => 3*3이므로
# 쿼드 트리와 다르게 2가 아닌 3으로 나눠줌
# 이 때, 3으로 딸랑 한 번 나눠 주는게 아님
# 0, 3, 6 이렇게 총 3 번 나눠줘야 하므로
# x, y에 각각 반복문을 사용하여 분할을 구현해준다
for k in range(3):
for l in range(3):
solution(x + k*n//3, y + l * n // 3, n//3)
return
# 위의 회귀로 실행된 반복문이 종료 된 후
# color변수에 남은 값에 따라서 개수를 증가시켜줌
if color == -1:
cnt_list[0] += 1
elif color == 0:
cnt_list[1] += 1
else:
cnt_list[2] += 1
return cnt_list
solution(0, 0, n)
for c in cnt_list:
print(c)
문제 해설
분할 정복 - 쿼드 트리의 응용 문제.
쿼드 트리와 달리 9분할을 하는 문제이다. 즉 3 * 3분할 이므로 주어진 그래프를 아래 코드와 같이 3의 배수에 맞게 나누어 주면 된다.
# 9개의 종이로 자름 => 3*3이므로
# 쿼드 트리와 다르게 2가 아닌 3으로 나눠줌
# 이 때, 3으로 딸랑 한 번 나눠 주는게 아님
# 0, 3, 6 이렇게 총 3 번 나눠줘야 하므로
# x, y에 각각 반복문을 사용하여 분할을 구현해준다
for k in range(3):
for l in range(3):
solution(x + k*n//3, y + l * n // 3, n//3)
문제에서 주어지는 n의 범위가 3의 7승으로 그리 크지 않으므로 4중 포문으로 문제를 해결하여도 시간 복잡도에 걸리지 않고 문제를 해결할 수 있다.
분할 정복의 경우 로직 자체는 익숙해지면 매우 간단한데 접할 기회가 잘 없어서 그런지 와닿지가 않는 특이한 문제이다. 백준에 있는 많은 분할 정복 문제를 풀어서 익혀야겠다.
댓글남기기