문제
지민이는 자신의 저택에서 MN개의 단위 정사각형으로 나누어져 있는 M×N 크기의 보드를 찾았다. 어떤 정사각형은 검은색으로 칠해져 있고, 나머지는 흰색으로 칠해져 있다. 지민이는 이 보드를 잘라서 8×8 크기의 체스판으로 만들려고 한다.
체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 한다. 구체적으로, 각 칸이 검은색과 흰색 중 하나로 색칠되어 있고, 변을 공유하는 두 개의 사각형은 다른 색으로 칠해져 있어야 한다. 따라서 이 정의를 따르면 체스판을 색칠하는 경우는 두 가지뿐이다. 하나는 맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우이다.
보드가 체스판처럼 칠해져 있다는 보장이 없어서, 지민이는 8×8 크기의 체스판으로 잘라낸 후에 몇 개의 정사각형을 다시 칠해야겠다고 생각했다. 당연히 8*8 크기는 아무데서나 골라도 된다. 지민이가 다시 칠해야 하는 정사각형의 최소 개수를 구하는 프로그램을 작성하시오.
내 코드
h, w = map(int, input().split())
board = []
chess = []
color = []
for i in range(h):
for j in list(input()):
board.append(j)
for i in range(h):
if(i % 2 == 0):
for j in range(w):
if (j % 2 == 0):
chess.append('W')
else:
chess.append('B')
else:
for j in range(w):
if (j % 2 == 0):
chess.append('B')
else:
chess.append('W')
for i in range(len(board)):
if(board[i] == chess[i]):
color.append(0)
else:
color.append(1)
colorCount1 = 64 #1 개수
colorCount0 = 64 #0 개수
for i in range(w * h - 7 * w):
if (i % w > w - 8):
continue
temCount1 = 0
temCount0 = 0
for j in range(8):
temCount1 += color[i + (w * j) : i + (w * j) + 8].count(1)
temCount0 += color[i + (w * j) : i + (w * j) + 8].count(0)
if (temCount1 < colorCount1):
colorCount1 = temCount1
if (temCount0 < colorCount0):
colorCount0 = temCount0
print(colorCount1 if (colorCount1 < colorCount0) else colorCount0)
과정
체스판을 색칠하는 경우는 두 가지(W로 시작 or B로 시작)라는 것부터 시작했다. 두 가지 경우를 모두 탐색할 필요는 없고 하나에 대해서만 계산한 뒤 반전시키면 된다. 굳이 2차원 배열을 만들 필요 없이 모든 값을 1차원 배열로 관리하며 필요할 경우 인덱스로 접근했다.
우선 입력 받은 판의 제일 왼쪽 위 색을 기준으로 비교군 배열 chess를 만든다. chess는 입력받은 판과 크기가 같은 체스판이다. 이후 색칠 필요 여부를 저장하는 배열 color에 chess와 board(입력 받은 판)를 비교해 색칠이 필요한 경우 1, 필요하지 않은 경우 0을 append한다. 이렇게 하면 필요한 데이터 정리는 모두 끝난다.
이 문제를 푼 핵심 방법은 color에서 1이 가장 적게 포함되어 있는 영역을 찾는 것이다. color를 순회하며 찾으면 되는데, 중요한 것은 자를 수 있는 영역인지를 확인하는 것이다. 이 부분은 각 줄에 대해
- (시작 인덱스 % 전체 너비)가 (전체 너비 -8)보다 작은지 확인
- (원하는 너비 = 8)칸 카운트
를 반복하여 구현했다.
이 때 줄을 넘어가다가 더 이상 체스판을 만들 수 없을 경우(남은 줄이 8 미만일 경우)는 제외하기 위해 반복문을 {전체 칸 수 - (원하는 높이 - 1) * (전체 너비)} 만큼만 반복한다.
앞서 만들 수 있는 체스 판의 경우의 수 두 가지를 모두 고려하지 않았다. 그 이유는 두 가지 경우를 모두 검사할 경우(예를 들어 chess 배열을 두 종류로 만든다든가) 중복된 계산이 발생하기 때문이다. 체스판을 두 가지 색깔만으로 이루어져 있기 때문에 색깔을 반전시키면 완전히 동일한 결과가 나오게 된다. 이 부분을 구현하기 위해 color에서 0의 개수와 1의 개수를 모두 카운트 한 후, 둘 중 더 작은 값을 출력했다.
'Algorithm' 카테고리의 다른 글
[14681] 사분면 고르기 - JavaScript (Node.js EACCESS 에러 수정) (0) | 2022.06.11 |
---|---|
JavaScript로 백준 문제 풀기(Node.js 사용) (0) | 2022.06.09 |
[1004] 어린 왕자 - Python (0) | 2022.01.24 |
[9461] 파도반 수열 - Python (0) | 2022.01.24 |
[11729] 하노이 탑 - Python (2) | 2022.01.23 |