🖥️ CS/Baekjoon Algorithms

#1018번 체스판 다시 칠하기 (c++)

한국의 메타몽 2020. 3. 1. 23:42
#include <iostream>
using namespace std;

void check(int w, int h){
    char board[w][h];
    int ori_ans = 2500; // 비교해야할 고치는 타일 수의 원본
    int ori_w = 0 ; int ori_h = 0; // 변하는 행,렬에서 [0][0]자리를 나타낼 값
    for(int i=0; i<w; i++){
        for(int j=0; j<h; j++)
            cin >> board[i][j];}
    while(!(ori_w+8>w)){ // 1. 시작을 블랙으로 잡은 경우
        int ans = 0;
        for(int i=ori_w; i<ori_w+8; i++){
            for(int j=ori_h; j<ori_h+8; j++){
                    if((i-ori_w)%2==0){
                        if((j-ori_h)%2==0&&board[i][j]!='B') ans++;
                        else if((j-ori_h)%2==1&&board[i][j]!='W') ans++;}
                    else if((i-ori_w)%2==1){
                        if((j-ori_h)%2==0&&board[i][j]!='W') ans++;
                        else if((j-ori_h)%2==1&&board[i][j]!='B') ans++;}
                }
        }
        if(ori_ans>=ans) ori_ans = ans;
        ori_h++;
        if(ori_h+8>h){ori_w++; ori_h=0;}
    }
    ori_w = 0; ori_h = 0;
    while(!(ori_w+8>w)){ // 2. 시작을 화이트로 잡은 경우
        int ans = 0;
            for(int i=ori_w; i<ori_w+8; i++){
                for(int j=ori_h; j<ori_h+8; j++){
                        if((i-ori_w)%2==0){
                            if((j-ori_h)%2==0&&board[i][j]!='W') ans++;
                            else if((j-ori_h)%2==1&&board[i][j]!='B') ans++;}
                        else if((i-ori_w)%2==1){
                            if((j-ori_h)%2==0&&board[i][j]!='B') ans++;
                            else if((j-ori_h)%2==1&&board[i][j]!='W') ans++;}
                }
        }
        if(ori_ans>=ans) ori_ans = ans;
        ori_h++;
        if(ori_h+8>h){
            ori_w++;ori_h=0;}
    }
    cout << ori_ans;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int M,N = 0;
    cin >> M >> N;
    check(M,N);
    
    return 0;
}

분명 1번과 2번을 합쳐서 코드를 이쁘고 간략하게 적는 방법이 있겠지만

그건 언젠가 시간이 날 때 하겠다...정답을  맞추고 나니 그다지 손대기가 싫고 귀찮아졌다...

 

문제를 읽다보면 대충 원리는 파악될 것이다.

하지만 기쁜마음에 정답을 채점하니 막상 틀리게 되었는데 , 곰곰이 보니 내가 문제를 잘 못 읽었음을 깨달았다. 

 

분명히 '색을 칠하는 경우가 2개' 라고 적혀있다.

말은 즉슨, 첫 판단의 단추가 단순히 '블랙'이냐, '화이트'이냐를 따지는게 아니라

'블랙'으로 칠해버릴 경우, '화이트'로 칠해버릴 경우 모두를 고려해서 더 적은 값을 판단해야하는 상황이다.

 

만약 위의 해설이 이해 안될 경우, 간단하게 아래의 예시를 테스트 케이스로 넣어보자.

 

8 8

BBBBWBBW

WWWWBBWB

WWBBWBWW

WBWWBWBW

WBBWBBWB

BWBWBWWB

BWWWWWBW

BWBBBBWW

 

만약 올바르게 공식을 적었다면 정답은 '29'가 나오겠지만,

나와 같은 실수를 겪었다면 다른 숫자가 나올것이다. (예를 들어 35라던가... 기억이 가물가물해서 숫자는 확실하지 않다.)

 

뭔가 복잡해보이지만 원리는 글을 조금만 집중해서 보면 나온다.

다만 그 논리를 어떻게 풀어쓰냐가 문제다.

 

나는 답변을 '이쁘고' '간략하게' 쓰는 것에 집착하다보니 문제를 푸는 속도가 더디는 것이 느껴졌다. 

덩달아 스트레스는 배가 되었다. 

 

하지만 백준을 한바퀴 돌리고 알고리즘 문제를 그만 풀 것도 아니다. 

 

꾸준히 풀것이기 때문에, 백준 1회차는 무사히 문제들을 All clear && 개념 이해에 목적을 두기로 결심했다.

그렇게 결심하니 문제를 푸는데 스트레스를 덜 받고 더 즐거워지기 시작했다. 

'🖥️ CS > Baekjoon Algorithms' 카테고리의 다른 글

#2550번 수 정렬하기 (c++)  (0) 2020.03.03
#1436번 영화감독 숌 (c++)  (0) 2020.03.03
#1568번 덩치 (c++)  (0) 2020.03.01
#2231번 분해합 (c++)  (0) 2020.03.01
#2789번 블랙잭 (c++)  (0) 2020.03.01