개발/algorithm
[백준 2630번] 색종이 만들기 - python
zzi_on2
2022. 2. 15. 15:10
문제 링크
https://www.acmicpc.net/problem/2630
2630번: 색종이 만들기
첫째 줄에는 전체 종이의 한 변의 길이 N이 주어져 있다. N은 2, 4, 8, 16, 32, 64, 128 중 하나이다. 색종이의 각 가로줄의 정사각형칸들의 색이 윗줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다.
www.acmicpc.net
풀이
- 분할 정복 문제
: 주어진 문제를 작은 문제로 분할하여 문제를 해결하는 방법으로, 재귀적으로 자기 자신을 호출하여 그 연산 단위를 줄여나가는 알고리즘이다.
- 평소 문제를 풀 때 재귀를 잘 사용하지 않고 분할 정복 문제를 처음 접해봐서 문제 해결 방법을 떠올리는게 쉽지 않았다.
- graph를 순회하면서 처음 시작한 graph[i][j]의 값과 달라지는 경우 범위를 4등분하여 재귀적으로 호출한다.
이 때 4등분하는 방식은 n을 2등분하고, 첫 시작점 좌표 값을 4등분 했을 때 각각의 첫 시작점 좌표로 설정해준다.
sol(x, y, n//2)
sol(x + n//2, y , n//2)
sol(x, y + n//2 , n//2)
sol(x + n//2, y + n//2, n//2)
- 처음 시작한 graph[i][j]의 값이 0일 때는 하얀색종이의 개수 +1
- 처음 시작한 graph[i][j]의 값이 1일 때는 파란색종이의 개수 + 1
# 분할 정복
# 흰색 색종이 개수
count0 = 0
# 파란 색종이 개수
count1 = 0
def sol(x, y, n):
global count0
global count1
color = graph[x][y]
for i in range(x, x+n):
for j in range(y, y+n):
# 처음 시작한 색과 다르면
if color != graph[i][j]:
# 4등분하여 재귀적으로 호출
sol(x, y, n//2)
sol(x+n//2 , y , n//2)
sol(x, y +n//2 , n//2)
sol(x+n//2, y+n//2, n//2)
return
# 흰색 색종이 개수 + 1
if color == 0:
count0 += 1
# 파란 색종이 개수 + 1
else:
count1 += 1
n = int(input())
graph = []
for _ in range(n):
graph.append(list(map(int,input().split())))
sol(0,0,n)
print(count0)
print(count1)