지극히 개인적인 공부 노트/알고리즘(Algorithm)
[Algorithm] 백준 1780번: 종이의 개수 | 분할 정복, 전역 변수
AS J
2021. 9. 1. 16:58
문제 출처: https://www.acmicpc.net/problem/1780

1. 결과
메모리 67648KB, 시간 3592ms
2. 풀이
분할 정복을 최근에 제대로 배워보면서 분할 정복과 재귀 호출을 연습하게 되는 계기가 되었다.
또한, 나로서는 이 문제에서 하나의 함수만으로 재귀 호출 후 답을 반환하는 아이디어가 쉽게 떠오르지 않았기 때문에 전역 변수를 사용했다. 각 함수 내에서 global을 통해 counts가 전역 변수임을 알렸는데, 이런 전역 변수 선언은 가장 함수의 맨 위에서 이루어져야 한다. 파이썬은 위에서부터 순서대로 읽어나가는 경향이 있기 때문에, 함수의 중후반에서 전역 변수 선언을 했을 때는 그 이전 줄에서 이 counts라는 변수를 읽지 못하고 오류가 발생했다.
오히려 전역 변수를 나중에 선언하는 것이 유리한 상황이 있을지는 모르겠지만, 그런 방식으로도 이용할 수는 있을 것이라는 생각을 해봤다.
import sys
# 종이 정보, 열 개수(n)를 입력으로 받음.
# n == 1이거나 단일색으로 이루어진 종이일 때 [(0, 0, 0)] 형태로 반환
# 색이 다르면 9등분으로 나누고 다시 진행
counts = [0] * 3
def countPaper(paper, x, y, n):
global counts
pivot = paper[y][x]
if n == 1:
counts[pivot] += 1
return
tri = n // 3
for i in range(y, y+n):
for j in range(x, x+n):
if pivot != paper[i][j]:
for a in range(3):
for b in range(3):
countPaper(paper, x+tri*b, y+tri*a, tri)
return
counts[pivot] += 1
return
def main():
global counts
N = int(sys.stdin.readline())
arr = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
countPaper(arr, 0, 0, N)
return counts
if __name__ == "__main__":
result = main()
print(result[-1])
for i in result[:-1]:
print(i)