ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C++) 백준 1018번: 체스판 다시 칠하기
    컴퓨터 공학/Problem Solving 2023. 3. 23. 21:34

    코딩 테스트 관련 포스팅은 당초 계획에 있지는 않았으나,

    1. 풀었지만 다른 사람의 풀이가 너무 좋은 경우

    2. 풀지 못하고 다른 사람의 풀이를 참고한 경우

    에는 정리 겸 글로 남기는 것도 나쁘지 않을 것 같다고 판단하여 하나씩 채워보려 한다.

     

    이번 문제는 백준 1018번이다.

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

     

    1018번: 체스판 다시 칠하기

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

    www.acmicpc.net

     

    < 접근 방식 1 - 실패 >

    좌측 상단 모서리를 기준으로 B인지 W인지 체크한 후, 체스판을 만들어서 최솟값을 구했다.

    무언가 느낌이 이상해서 문제를 다시 생각해보니 좌측 상단 모서리가 B인지 W인지 체크하는 것이 아니라 B도 될 수 있고 W도 될 수 있는 것이었다. 따라서 문제 해석을 잘못함.

    문제를 똑바로 읽고 이해부터 하자.

     

    < 접근 방식 2 - 실패 >

    이번엔 문제는 제대로 이해한 듯 하다.

    1. 좌측 상단 모서리를 기준으로 B일 떄 W일 때를 모두 염두에 두고 8 x 8 체스판을 둘 다 만들어 최솟값을 하나씩 확인해본다.

    2. 8 x 8 체스판을 만들 때는 반복문의 조건자(보통 i, j 등으로 쓰는 것)를 짝수 혹은 홀수를 기준으로 B나 W의 값이 본래 있어야하는 값과 다르면 count를 센다.

    e.g)

    if (i % 2 == 0 && j % 2 == 0) {

      if (arr[i][j] == 'W') count++;

    }

    대충 이런 식인데...식이 굉장히 복잡해졌다. 맞았다면 그나마 다행인데, 하필 TC가 모두 통과되지 않아서 보기도 힘든 코드를 수정하느라 굉장히 애먹었다. 근데 결국 이렇게 하고도 안됐음. 한 1시간 반 정도 보다가 다른 풀이를 택하기로 했다.

     

    < 접근 방식 3 - 성공 >

    옛날에 DP 문제들을 풀 때, 모양을 만들어 놓는 것을 차용하여 배열을 미리 만들어놓고 비교하는 것을 선택했다.

    1. 8 x 8의 BWBW ... 배열과 WBWB ... 배열을 미리 만들어 놓음.

    2. 좌측 상단 모서리를 기준으로 8 x 8 배열을 미리 만들어 놓은 배열과 비교하여 다른 것만 바꿔주고 count를 셈.

    처음부터 이렇게 할 걸 그랬다. 코드도 훨씬 단순해지고 시간도 적게 걸렸다. 역시 문제 풀이는 처음에 길을 잘 들어가는 것이 베스트인 듯. 물론 그게 어려운 거겠지만..

     

    아래는 전체 코드이다.

     

    #include <iostream>
    #include <algorithm>
    #include <cstring>

    using namespace std;

    char bw[8][9] = {
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    };
    char wb[8][9] = {
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'},
    {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'},
    };

    int main()
    {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int N, M;
    cin >> N >> M;

    char** arr_original = new char* [N];
    for (int i = 0; i < N; i++) {
    arr_original[i] = new char[M];
    }
    for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
    cin >> arr_original[i][j];
    }
    }

    int count_bw = 0;
    int count_wb = 0;
    int min = 65;
    for (int i = 0; i <= N - 8; i++) {
    for (int j = 0; j <= M - 8; j++) {
    for (int k = i, m = 0; k < i + 8; k++, m++) {
    for (int l = j, n = 0; l < j + 8; l++, n++) {
    if (bw[m][n] != arr_original[k][l]) {
    count_bw++;
    }
    if (wb[m][n] != arr_original[k][l]) {
    count_wb++;
    }
    }
    }
    if (min > count_bw)
    min = count_bw;
    if (min > count_wb)
    min = count_wb;
    count_bw = 0;
    count_wb = 0;
    }
    }

    cout << min;

    for (int i = 0; i < N; i++) {
    delete[] arr_original[i];
    }
    delete[] arr_original;

    return 0;
    }

Designed by Tistory.