Algorithm/Divide&Conquer

[백준] 1780 종이의 개수 (Python 파이썬)

안드선생 2021. 9. 19. 14:49
반응형

https://www.acmicpc.net/problem/1780

 

1780번: 종이의 개수

N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다. 만약 종이가 모두 같은 수

www.acmicpc.net

문제 설명

N×N크기의 행렬로 표현되는 종이가 있다. 종이의 각 칸에는 -1, 0, 1 중 하나가 저장되어 있다. 우리는 이 행렬을 다음과 같은 규칙에 따라 적절한 크기로 자르려고 한다.

  1. 만약 종이가 모두 같은 수로 되어 있다면 이 종이를 그대로 사용한다.
  2. (1)이 아닌 경우에는 종이를 같은 크기의 종이 9개로 자르고, 각각의 잘린 종이에 대해서 (1)의 과정을 반복한다.

이와 같이 종이를 잘랐을 때, -1로만 채워진 종이의 개수, 0으로만 채워진 종이의 개수, 1로만 채워진 종이의 개수를 구해내는 프로그램을 작성하시오.


풀이 과정

이전에 올렸던 쿼드트리(https://hongcoding.tistory.com/86?category=973613) 문제와 굉장히 유사하다.

쿼드트리 문제가 4구역으로 나눈 분할정복 문제라면

이번 문제는 9구역으로 나눈 분할정복 문제이다.

 

푸는 방식도 동일하다.

한 구역안에 모든 숫자가 같은 숫자로 이루어져 있지 않으면

같은 숫자로 이루어질 때 까지 계속 구역을 분할하며 풀어나가는 분할 정복 문제이다.

 

파이썬 코드는 다음과 같다.

n = int(input())


def recursive(x, y, N):
    flag = False

    for i in range(x, x + N):
        if flag:
            break

        for j in range(y, y + N):
            if graph[x][y] != graph[i][j]:
                recursive(x, y, N // 3)
                recursive(x, y + N // 3, N // 3)
                recursive(x, y + (N // 3 * 2), N // 3)
                recursive(x + N // 3, y, N // 3)
                recursive(x + N // 3, y + N // 3, N // 3)
                recursive(x + N // 3, y + (N // 3 * 2), N // 3)
                recursive(x + N // 3 * 2, y, N // 3)
                recursive(x + N // 3 * 2, y + N // 3, N // 3)
                recursive(x + N // 3 * 2, y + (N // 3 * 2), N // 3)

                flag = True
                break

    if not flag:
        if graph[x][y] == -1:
            count[0] += 1
        elif graph[x][y] == 0:
            count[1] += 1
        elif graph[x][y] == 1:
            count[2] += 1


graph = []
for i in range(n):
    graph.append(list(map(int, input().split())))

count = [0, 0, 0]
recursive(0, 0, n)

for i in count:
    print(i)

https://github.com/HongEunho

전체 문제 & 코드는 위의 깃에 정리되어 있습니다.

팔로우 & 맞팔은 환영입니다 !

반응형