https://www.acmicpc.net/problem/1780
1780번: 종이의 개수
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수
www.acmicpc.net
1. 문제 조건 정리(변형)
a) R(-1), G(0), B(1)이 있는 큰 종이가 있습니다.
b) 단색이면 자르지 않고 해당 색 개수를 늘립니다.
c) 단색이 아니면 9등분을 하여 위 과정을 다시 반복합니다.
2. 입력 데이터
- N = 3^7 = 약 2000개 입니다
3. 아이디어
- 영역을 줄여나가며 구현만 하면 됩니다.
- 반복과정이 있으니 재귀함수를 사용하면 됩니다.
- 매번 N^2으로 단색인지를 확인하여야 합니다.
- 9등분한 영역을 재귀 호출하므로(확인 요망)
- O(N^2 * logN) 입니다.
5. 구현
a) 종료 조건
- 모두 단색인 경우 자르지 않으므로 단색일 때 함수를 종료합니다.
- 어쩔 수 없이 모든 값을 순회하여야 같은 색임을 알 수 있습니다.*
b) 재귀 함수 호출
- 9등분한 영역에 대한 재귀함수를 호출합니다.
c) 파라미터
- 현재 종이의 크기와 절대 좌표 값을 알아야 합니다.
- 저는 좌상단을 기준으로 한 row, col 값과 size값을 파라미터로 설정하였습니다.
6. 문법
- 2차원 배열 선언 : paper = [[int(x) for x in input().split()]for y in range(n)]
7. 코드
def isSameKind(sr, sc, sz):
global paper
color = paper[sr][sc]
for r in range(sr, sr + sz):
for c in range(sc, sc + sz):
if paper[r][c] != color:
return False
return True
def cutPaper(sr, sc, sz):
if isSameKind(sr, sc, sz):
global paper, paperCnt
paperCnt[paper[sr][sc]] += 1
return
newSz = sz//3
for i in range(3):
for j in range(3):
cutPaper(sr + i*newSz, sc + j*newSz, newSz)
n = int(input())
paper = [[int(x) for x in input().split()]for y in range(n)]
paperCnt = [0, 0, 0]
cutPaper(0, 0, n)
print(paperCnt[-1])
print(paperCnt[0])
print(paperCnt[1])
8. 추가 사항
- * 누적합을 통한 성능향상이 가능할지 모르겠습니다..
'코딩 테스트 준비 > 재귀' 카테고리의 다른 글
[프로그래머스] 타겟넘버 (0) | 2022.01.19 |
---|