https://www.acmicpc.net/problem/1780
1780번: 종이의 개수
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수
www.acmicpc.net
문제
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다.
- 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다.
- (1)이 아닌 경우에는 종이를 같은 크기의 종이 9개로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다.
이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으로만 채워진 종이의 개수, 1로만 채워진 종이의 개수를 구해내는 프로그램을 작성하시오.
입력
첫째 줄에 N(1 ≤ N ≤ 37, N은 3k 꼴)이 주어진다. 다음 N개의 줄에는 N개의 정수로 행렬이 주어진다.
출력
첫째 줄에 -1로만 채워진 종이의 개수를, 둘째 줄에 0으로만 채워진 종이의 개수를, 셋째 줄에 1로만 채워진 종이의 개수를 출력한다.
풀이
자른 조각 내의 숫자가 모두 동일해질 때까지 반복해야 하는 분할 정복 문제이다. 매 반복마다 9조각으로 조개야 하므로 영역을 분할할 때 분할하는 조각의 size는 분할 전 조각의 1/3이 되어야 한다. 분할이 종료되고 나면 -1로만 이루어진 조각 수, 0으로만 이루어진 조각 수, 1로만 이루어진 조각 수를 프린트해준다.
# 백준 1780 종이의 개수 실버2 https://www.acmicpc.net/problem/1780
# n x n 행렬에서, 모두 같은 수로 되어 있지 않다면 9개로 자른다.
# 분할정복
n = int(input())
graph = []
for _ in range(n):
graph.append(list(map(int, input().split())))
minus_one_cnt = 0
zero_cnt = 0
one_cnt = 0
def divide(start_row, start_col, size):
global minus_one_cnt, zero_cnt, one_cnt
num = graph[start_row][start_col]
for i in range(start_row, start_row+size):
for j in range(start_col, start_col+size):
if graph[i][j] != num:
size //= 3
divide(start_row, start_col, size)
divide(start_row+size, start_col, size)
divide(start_row+(2*size), start_col, size)
divide(start_row+(2*size), start_col+size, size)
divide(start_row+size, start_col+size, size)
divide(start_row, start_col+size, size)
divide(start_row, start_col+(2*size), size)
divide(start_row+size, start_col+(2*size), size)
divide(start_row+(2*size), start_col+(2*size), size)
return
else:
if num == -1:
minus_one_cnt += 1
elif num == 0:
zero_cnt += 1
else:
one_cnt += 1
divide(0,0, n)
print(minus_one_cnt, zero_cnt, one_cnt)
divide 함수는 시작할 행 인덱스(start_row), 시작할 열 인덱스(start_col), 그리고 탐색할 영역의 크기인 size를 입력으로 받는다. 그리고 영역의 각 원소를 탐색하면서 다른 숫자를 발견하면 재귀적으로 분할을 수행한다. 이때 9개의 영역을 분할할 수 있도록, 분할할 영역별로 divide를 수행해준다.
만약 for문을 모두 통과했다면 영역 내의 숫자가 모두 동일하다는 것을 의미하므로, 영역을 이룬 숫자가 무엇인지에 따라서 minus_one_cnt, zero_cnt, one_cnt 를 업데이트해준다.
'알고리즘' 카테고리의 다른 글
[백준 5430] AC (골드5) Python 풀이 (0) | 2023.04.25 |
---|---|
[백준 9019] DLSR (골드4) Python (0) | 2023.04.24 |
[백준 1697] 숨바꼭질 (실버 1) Python (0) | 2023.04.23 |
[백준 9461] 파도반 수열 (실버 2) Python (0) | 2023.04.23 |
[백준 2630] 색종이 만들기 (실버 2) Python (0) | 2023.04.21 |