백준(BaekJoon)

[BaekJoon/C] No.1018 : 체스판 다시 칠하기

ekdnjs510 2024. 11. 7. 22:18
728x90

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

 

소스코드 & 문제풀이

 

#include <stdio.h>

int main(void)
{
    // 2차원 배열을 통해 체스판을 구현합니다.
    // 배열의 크기는 조건을 만족시키기 위해 최대 50줄과 51개의 열로 설정합니다.
    char arr[50][51];

    // 체스판의 행 개수 (a)와 열 개수 (b)를 입력받고, count를 큰 값으로 초기화합니다.
    int a, b, count = 3000;
    
    // 체스판의 행과 열을 입력받습니다.
    scanf("%d%d", &a, &b);

    // 체스판 데이터를 배열 arr에 행 단위로 저장합니다.
    for (int i = 0; i < a; i++)
        scanf("%s", arr[i]);

    // 체스판 첫 번째 칸을 'W' 또는 'B'로 시작하는 경우를 각각 계산할 임시 변수 초기화.
    int temp1 = 0, temp2 = 0;

    // 체스판에서 가능한 모든 8x8 크기의 부분 체스판을 탐색합니다.
    // (x, y)를 8x8 그리드의 좌측 상단으로 하여 모든 가능한 시작 위치에서 반복합니다.
    for (int x = 0; x < a - 7; x++) {
        for (int y = 0; y < b - 7; y++) {
            
            // 첫 번째 칸이 'W'일 때 8x8 그리드를 검사합니다.
            for (int i = x; i < x + 8; i++) {
                for (int j = y; j < y + 8; j++) {
                    // i와 j의 합이 짝수인 경우, 해당 칸은 'W'가 되어야 합니다.
                    if (((i - x + j - y) % 2) == 0) {
                        if (arr[i][j] != 'W') // 칸이 'W'가 아니면 다시 칠합니다.
                            temp1++;
                    }
                    // i와 j의 합이 홀수인 경우, 해당 칸은 'B'가 되어야 합니다.
                    else {
                        if (arr[i][j] != 'B') // 칸이 'B'가 아니면 다시 칠합니다.
                            temp1++;
                    }
                }
            }

            // 첫 번째 칸이 'B'일 때 8x8 그리드를 검사합니다.
            for (int i = x; i < x + 8; i++) {
                for (int j = y; j < y + 8; j++) {
                    // i와 j의 합이 짝수인 경우, 해당 칸은 'B'가 되어야 합니다.
                    if (((i - x + j - y) % 2) == 0) {
                        if (arr[i][j] != 'B') // 칸이 'B'가 아니면 다시 칠합니다.
                            temp2++;
                    }
                    // i와 j의 합이 홀수인 경우, 해당 칸은 'W'가 되어야 합니다.
                    else {
                        if (arr[i][j] != 'W') // 칸이 'W'가 아니면 다시 칠합니다.
                            temp2++;
                    }
                }
            }

            // 현재 8x8 그리드에서 더 적게 칠한 횟수를 선택하고, `count`가 가장 작은 값을 저장합니다.
            int res = temp1 < temp2 ? temp1 : temp2;
            if (res < count) count = res;

            // 다음 8x8 그리드를 위해 임시 repaint 횟수를 초기화합니다.
            temp1 = 0;
            temp2 = 0;
        }
    }

    // 최소 칠해야 하는 횟수를 출력합니다.
    printf("%d", count);

    return 0;
}

 

제 입출력 결과

 

 

728x90