개발자가 내팔자

[BOJ] 백준 1780 종이의 개수 Python 본문

Algorithms

[BOJ] 백준 1780 종이의 개수 Python

야생의 개발자 2022. 7. 30. 01:50

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

 

1780번: 종이의 개수

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

www.acmicpc.net

 

전체적인 로직을 짜는 건 익숙한데 디테일에서 계속 삽질을 하는 것 같다.

집중해서 잘 해봐야지

import sys

N = int(sys.stdin.readline())

result = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]

def is_full(N, start_pos, start_value):
    x, y = start_pos
    for i in range(N):
        for j in range(N):
            if result[y + j][x + i] != start_value:
                return False
    return True

def get_pos(N, start_pos):
    x, y = start_pos
    return [(x + (N * i)//3, y + (N * j)//3) for i in range(3) for j in range(3)]

paper_count = [0, 0, 0]

def solution(N, paper, paper_count, pos=(0, 0)):
    i, j = pos
    if N == 1 or is_full(N, pos, paper[j][i]):
        paper_count[paper[j][i] + 1] += 1
        return
    else:
        poses = get_pos(N, pos)
        for pos in poses:
            i, j = pos
            solution(N//3, paper, paper_count, pos)
    return
    

solution(N, result, paper_count)
for paper in paper_count:
    print(paper)

 

 

아래는 바킹독 코드

import sys

N = int(sys.stdin.readline())
paper = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]


def check(x, y, n):
    for i in range(x, x + n):
        for j in range(y, y + n):
            if paper[x][y] != paper[i][j]:
                return False
    return True

paper_count = [0, 0, 0]

def solve(x, y, z):
    if check(x, y, z):
        paper_count[paper[x][y] + 1] += 1
        return
    n = z // 3
    for i in range(3):
        for j in range(3):
            solve(x + i * n, y + j * n, n)

solve(0, 0, N)

for paper in paper_count:
    print(paper)

 

Comments