# [Algorithm/JS] 백준 1018번 체스판 다시 칠하기
# Question
지민이는 자신의 저택에서 MN개의 단위 정사각형으로 나누어져 있는 M×N 크기의 보드를 찾았다. 어떤 정사각형은 검은색으로 칠해져 있고, 나머지는 흰색으로 칠해져 있다. 지민이는 이 보드를 잘라서 8×8 크기의 체스판으로 만들려고 한다.
체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 한다. 구체적으로, 각 칸이 검은색과 흰색 중 하나로 색칠되어 있고, 변을 공유하는 두 개의 사각형은 다른 색으로 칠해져 있어야 한다. 따라서 이 정의를 따르면 체스판을 색칠하는 경우는 두 가지뿐이다. 하나는 맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우이다.
보드가 체스판처럼 칠해져 있다는 보장이 없어서, 지민이는 8×8 크기의 체스판으로 잘라낸 후에 몇 개의 정사각형을 다시 칠해야겠다고 생각했다. 당연히 8*8 크기는 아무데서나 골라도 된다. 지민이가 다시 칠해야 하는 정사각형의 최소 개수를 구하는 프로그램을 작성하시오.
# Input
첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.
# Output
첫째 줄에 지민이가 다시 칠해야 하는 정사각형 개수의 최솟값을 출력한다.
# Example
# Input 1
8 8
WBWBWBWB
BWBWBWBW
WBWBWBWB
BWBBBWBW
WBWBWBWB
BWBWBWBW
WBWBWBWB
BWBWBWBW
2
3
4
5
6
7
8
9
# Output 1
1
# Input 2
10 13
BBBBBBBBWBWBW
BBBBBBBBBWBWB
BBBBBBBBWBWBW
BBBBBBBBBWBWB
BBBBBBBBWBWBW
BBBBBBBBBWBWB
BBBBBBBBWBWBW
BBBBBBBBBWBWB
WWWWWWWWWWBWB
WWWWWWWWWWBWB
2
3
4
5
6
7
8
9
10
11
# Output 2
12
# Input 3
8 8
BWBWBWBW
WBWBWBWB
BWBWBWBW
WBWBWBWB
BWBWBWBW
WBWBWBWB
BWBWBWBW
WBWBWBWB
2
3
4
5
6
7
8
9
# Output 3
0
더 많은 예제는 상단 url에서 확인
# Solution
문제의 요지를 잘 파악해야한다. 문제에서 체스판은 8x8이라고 했으므로 입력값으로 8x8보다 큰 보드를 받아오더라도 보드 내에서 수정횟수가 가장 적은 8x8 범위를 체크해야한다. 처음에 문제를 잘못 이해해서 입력값으로 받아온 체스판 크기 전체를 체크했었다.
입력값은 모든 공백을 제거하는 정규식을 통해 M, N, board 를 받아왔고, 맨 위 왼쪽 첫번째 칸이 흰색인 경우(white
)와, 검은색인 경우(black
) 를 라인을 분리하여 배열로 준비했다.
const fs = require('fs');
const [M, N, ...board] = fs.readFileSync('../input.txt').toString().trim().split(/\s+/);
const white = [
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
];
const black = [
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- 입력받은 전체 보드판의 크기에서 8x8범위로 모든 경우의 수를 검사한다
- 8x8 범위의 수정이 필요한 칸 수를 찾아내는 함수
보드판 칸을
white
/black
보드와 비교했을 경우 수정해야할 횟수를 각whiteCk
/blackCk
변수에 저장한다. whiteCk
와blackCk
중 횟수가 적은 경우를 min 변수에 할당하여 최종적으로 최소 횟수를 출력한다.
// 1
for (let i = 0; i <= M - 8; i++) {
for (let j = 0; j <= N - 8; j++) {
check(i, j);
}
}
// 2
function check(x, y) {
let whiteCk = 0;
let blackCk = 0;
for (let i = x; i < x + 8; i++) {
for (let j = y; j < y + 8; j++) {
if (board[i][j] !== white[i - x][j - y]) whiteCk++;
if (board[i][j] !== black[i - x][j - y]) blackCk++;
}
}
let min = Math.min(whiteCk, blackCk); // 3
if (min < result) result = min;
}
console.log(result);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 전체 풀이
const fs = require('fs');
const [M, N, ...board] = fs.readFileSync('../input.txt').toString().trim().split(/\s+/);
const white = [
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
];
const black = [
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
'BWBWBWBW',
'WBWBWBWB',
];
let result = 64;
for (let i = 0; i <= M - 8; i++) {
for (let j = 0; j <= N - 8; j++) {
check(i, j);
}
}
function check(x, y) {
let whiteCk = 0;
let blackCk = 0;
for (let i = x; i < x + 8; i++) {
for (let j = y; j < y + 8; j++) {
if (board[i][j] !== white[i - x][j - y]) whiteCk++;
if (board[i][j] !== black[i - x][j - y]) blackCk++;
}
}
let min = Math.min(whiteCk, blackCk);
if (min < result) result = min;
}
console.log(result);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
← 7568번 덩치 1436번 영화감독 숌 →