Algorithm
백준 1780번 <종이의 개수>
seungh2
2022. 5. 10. 16:42
백준 알고리즘 1780번
https://www.acmicpc.net/problem/1780
1780번: 종이의 개수
N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수
www.acmicpc.net
1780번
N×N크기의 행렬로 표현되는 종이가 주어졌을 때, 아래와 같은 규칙에 따라 적절한 크기로 자르려고 한다.
- 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다.
- (1)이 아닌 경우에는 종이를 같은 크기의 종이 9개로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다.
이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으로만 채워진 종이의 개수, 1로만 채워진 종이의 개수를 구하여라.
입력으로 첫 줄에 종이의 크기 N이 들어오고 그 다음 N개의 줄에 걸쳐 종이에 대한 정보가 들어온다.
출력으로 -1, 0, 1로 이루어진 종이의 개수를 출력하면 된다.
문제 해결
종이의 크기는 3의 승수꼴이다.
주어진 종이가 같은 숫자로 이루어져있는지 확인하고 같은 숫자로 이루어져있다면 해당 숫자의 count 값을 1 증가시키고 그렇지 않다면 종이를 9개로 자른다.
종이를 slicing 하는 것이 매우 중요하다. 파이썬에서 2차원 배열을 slicing 하는 것을 구현해야 하는데 너무 어려웠다.
- paper의 숫자가 같은 숫자로 이루어져있는지 확인한다.
- 같은 숫자로 이루어져있으면 해당 숫자에 대해 count한다.
- 같은 숫자로 이루어져있지 않으면 종이를 slicing 한다.
- slicing한 종이에 대해 각각 answer 함수를 호출한다.
count한 값을 리스트에 저장했는데 종이를 이루는 숫자는 -1, 0, 1이기 때문에 각각을 index로 사용하면 된다.
그러면 [0으로 이루어진 종이의 개수, 1으로 이루어진 종이의 개수, -1으로 이루어진 종이의 개수]로 리스트에 저장된다.
코드
import sys
input = sys.stdin.readline
n = int(input())
paper = [list(map(int, input().split())) for _ in range(n)]
def same(n_, paper_):
if n_ == 1:
return True
chk = paper_[0][0]
for i in range(n_):
for j in range(n_):
if chk != paper_[i][j]:
return False
return True
def answer(n_, paper_):
cnt = [0, 0, 0]
if same(n_, paper_):
cnt[paper_[0][0]] += 1
return cnt
tempN = n_ // 3
for i in range(3):
arr = paper_[i*tempN : (i+1)*tempN]
for j in range(3):
temp = [arr[k][j*tempN : (j+1) * tempN] for k in range(tempN)]
recursion = answer(tempN, temp)
cnt = [cnt[i] + recursion[i] for i in range(3)]
return cnt
result = answer(n, paper)
print(result[-1])
print(result[0])
print(result[1])
결과
728x90