본문 바로가기
Algorithm Problem Solving/BaekJoon

[BaekJoon] 백준 1018 체스판 다시 칠하기 (Python / 파이썬)

by ʚ⇜❅🎕̈❄⇝ɞ 2021. 9. 17.
728x90
반응형

BaekJoon BOJ 백준 1018 체스판 다시 칠하기 문제는 M*N 크기의 보드를 잘라서 8*8 크기의 체스판으로 만들려고 한다. 보드가 체스판처럼 칠해져 있다는 보장이 없을 때, 다시 칠해야 하는 정사각형의 최소 개수를 구하는 문제이다. 난이도는 Silver 5이다.

 

BaekJoon 1018 체스판 다시 칠하기 문제 정보

출처

- https://www.acmicpc.net/problem/1018

알고리즘 분류

- 브루트 포스 알고리즘 (brute force algorithm)

난이도

- 실버 5 / Silver 5

 

체스판 다시 칠하기 문제 요약

  • 지민이는 자신의 저택에서 MN개의 단위 정사각형으로 나누어져 있는 M*N 크기의 보드를 찾았다. 어떤 정사각형은 검은색으로 칠해져 있고, 나머지는 흰색으로 칠해져 있다. 지민이는 이 보드를 잘라서 8*8 크기의 체스판으로 만들려고 한다.
  • 체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 한다. 구체적으로, 각 칸이 검은색과 흰색 중 하나로 색칠되어 있고, 변을 공유하는 두 개의 사각형은 다른 색으로 칠해져 있어야 한다. 따라서 이 정의를 따르면 체스판을 색칠하는 경우는 두 가지뿐이다. 하나는 맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우이다.
  • 보드가 체스판처럼 칠해져 있다는 보장이 없어서, 지민이는 8*8 크기의 체스판으로 잘라낸 후에 몇 개의 정사각형을 다시 칠해야겠다고 생각했다. 당연히 8*8 크기는 아무데서나 골라도 된다. 지민이가 다시 칠해야 하는 정사각형의 최소 개수를 구하여 출력한다.
  • N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다.

 

문제 풀이 과정

  1. 보드를 8*8 크기로 자를 곳의 범위를 정한다.
  2. 자른 보드에 맨 왼쪽 위 칸이 흰색인 경우는 (홀수 행, 홀수 열)과 (짝수 행, 짝수 열)이 흰색 이어야 하는데, 흰색이 아닌 경우는 다시 칠할 횟수를 카운트한다.
  3. 자른 보드에 맨 왼쪽 위 칸이 검은색인 경우는 (홀수 행, 홀수 열)과 (짝수 행, 짝수 열)이 검은색 이어야 하는데, 검은색이 아닌 경우는 다시 칠할 횟수를 카운트한다.
  4. 위 두 가지 경우 중에서 다시 칠하는 횟수가 더 적은 횟수를 저장해 놓는다.
  5. 보드를 자를 수 있는 모든 경우, 두 가지의 색칠하는 경우를 모두 탐색했을 때 다시 칠해야 하는 정사각형의 최소 개수를 구하여 출력한다.

 

코드 및 설명
  • change - 고른 모든 보드의 경우 중에서 다시 칠하는 최소 횟수
  • changeTmp -  현재 고른 보드 내에서 다시 칠하는 최소 횟수
  • changeCnt -  체스판을 칠하는 두 가지 경우에서 다시 칠하는 횟수
N, M = map(int, input().split())
board = [input() for _ in range(N)]
change = 65
for rowStart in range(N - 7):  # 보드 시작 행
    for colStart in range(M - 7):  # 보드 시작 열
        changeTmp = 65
        # 체스판을 칠하는 두 가지 경우
        for coloring in range(2):  # 맨 왼쪽 위칸 이 0: 흰색, 1: 검은색
            changeCnt = 0  # 현재 보드의 두 가지 경우에서 다시 칠하는 횟수
            for row in range(rowStart, rowStart + 8):
                for col in range(colStart, colStart + 8):
                    if (row % 2 == 0 and col % 2 == 0) or (row % 2 == 1 and col % 2 == 1):
                        if (coloring == 0 and board[row][col] != 'W') or (coloring == 1 and board[row][col] != 'B'):
                            changeCnt += 1
                    else:
                        if (coloring == 0 and board[row][col] != 'B') or (coloring == 1 and board[row][col] != 'W'):
                            changeCnt += 1

            # 현재 고른 보드 내에서 다시 칠하는 최소 횟수
            changeTmp = min(changeTmp, changeCnt)
        # 고른 모든 보드 중에서 다시 칠하는 최소 횟수
        change = min(change, changeTmp)
        
print(change)

BaekJoon 백준 BOJ 1018 체스판 다시 칠하기 문제를 파이썬 python 브루트 포스 알고리즘으로 풀어보았다. 난이도는 Silver 실버 5이다. 

728x90
반응형

댓글