본문 바로가기

완전 탐색 (Brute Force)

백준 1018 체스판 다시 칠하기

문제 링크: https://www.acmicpc.net/problem/1018

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

가능한 모든 8 X 8 체스판마다 다시 칠해야 하는 정사각형의 갯수를 세고, 그중 최소값을 구하면 된다.

다시 칠해야 하는 정사각형 갯수의 최소값을 구할때, BWBWB...로 시작하는 보드와 WBWBW...로 시작하는 보드 둘다와 비교해봐야 한다.

아래는 위와 같이 구현하여 처음 AC를 받은 코드이다.

1
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
#include <bits/stdc++.h>
using namespace std;
 
int n, m;
char a[51][51];
 
int toPaint(int y, int x) {
    int ret = 1e9;
    int cnt = 0;
    for(int i = y; i < y + 8; i++for(int j = x; j < x + 8; j++) {
        if((i + j) % 2 == 0 && a[i][j] == 'B') cnt++;
        if((i + j) % 2 != 0 && a[i][j] == 'W') cnt++;
    }
    ret = min(ret, cnt);
 
    cnt = 0;
    for(int i = y; i < y + 8; i++for(int j = x; j < x + 8; j++) {
        if((i + j) % 2 == 0 && a[i][j] == 'W') cnt++;
        if((i + j) % 2 != 0 && a[i][j] == 'B') cnt++;
    }
    ret = min(ret, cnt);
 
    return ret;
}
 
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
 
    cin >> n >> m;
    for(int i = 0; i < n; i++for(int j = 0; j < m; j++)
        cin >> a[i][j];
 
    int ans = 1e9;
    for(int i = 0; i <= n - 8; i++for(int j = 0; j <= m - 8; j++)
        ans = min(ans, toPaint(i, j));
 
    cout << ans << '\n';
    return 0;
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

위에서 BWBWB...로 시작하는 보드와 WBWBW...로 시작하는 보드 둘다와 비교해봐야 한다고 했는데, 사실상 이부분이 쓸데없이 코드를 길게만드는 부분이었다. BWBWB...로 시작하는 보드와 비교했을때 다시 칠해야 하는 정사각형 갯수가 x라고 하면, WBWBW...로 시작하는 보드와 비교했을때 다시 칠해야 하는 정사각형 갯수는 무조건 64 - x가 된다. 따라서 아래 코드와 같이 toPaint 함수의 길이를 짧게 고칠수 있다.

1
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
#include <bits/stdc++.h>
using namespace std;
 
int n, m;
char a[51][51];
 
int toPaint(int y, int x) {
    int ret = 1e9;
    int cnt = 0;
    for(int i = y; i < y + 8; i++for(int j = x; j < x + 8; j++) {
        if((i + j) % 2 == 0 && a[i][j] == 'B') cnt++;
        if((i + j) % 2 != 0 && a[i][j] == 'W') cnt++;
    }
    return min({ret, cnt, 64 - cnt});
}
 
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
 
    cin >> n >> m;
    for(int i = 0; i < n; i++for(int j = 0; j < m; j++)
        cin >> a[i][j];
 
    int ans = 1e9;
    for(int i = 0; i <= n - 8; i++for(int j = 0; j <= m - 8; j++)
        ans = min(ans, toPaint(i, j));
 
    cout << ans << '\n';
    return 0;
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

'완전 탐색 (Brute Force)' 카테고리의 다른 글

백준 1107 리모컨  (0) 2020.04.29
백준 1476 날짜 계산  (0) 2020.04.29
백준 2503 숫자 야구  (0) 2020.04.24
백준 10448 유레카 이론  (0) 2020.04.23
백준 3085 사탕 게임  (0) 2020.04.23