본문 바로가기
알고리즘/백준

백준 1018번 - 체스판 다시 칠하기 (Java 8)

by latissimus 2022. 3. 1.

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

 

1018번: 체스판 다시 칠하기

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

www.acmicpc.net

처음 짠 코드(괴물)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String args[]) throws IOException {
        final int HEIGHT_OF_CHESSBOARD = 8;
        final int WIDTH_OF_CHESSBOARD = 8;

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int height = Integer.parseInt(st.nextToken());
        int width = Integer.parseInt(st.nextToken());
        char[][] chessBoard = new char[height][width];

        for(int i=0; i<height; i++){ //String 배열에 한줄 씩 넣기
            chessBoard[i] = br.readLine().toCharArray();
        }

        int smallerNum = 0;
        int min = 2501;
        int numOfChessBoardInColumn = height-HEIGHT_OF_CHESSBOARD+1; //열에 들어갈 수 있는 8X8 체스보드 수
        int numOfChessBoardInRow = width-WIDTH_OF_CHESSBOARD+1; //행에 들어갈 수 있는 8X8 체스보드 수
        for(int i=0; i<numOfChessBoardInColumn; i++){
            for(int j=0; j<numOfChessBoardInRow; j++){
                int count = 0;
                for(int k=i; k<HEIGHT_OF_CHESSBOARD+i; k++){
                    for(int l=j; l<WIDTH_OF_CHESSBOARD+j; l++){
                        if(k % 2 == 0 && l % 2 == 0 && chessBoard[k][l] == 'B'){  //첫 칸을 W(WB형태)로 맞추려고 할때 바꿔야할 개수 세기
                            count++;
                        }
                        if(k % 2 == 1 && l % 2 == 1 && chessBoard[k][l] == 'B'){
                            count++;
                        }
                        if(k % 2 == 0 && l % 2 == 1 && chessBoard[k][l] == 'W'){
                            count++;
                        }
                        if(k % 2 == 1 && l % 2 == 0 && chessBoard[k][l] == 'W'){
                            count++;
                        }
                    }
                }
                //W 시작, B 시작하는 체스판 중 더 효율이 좋은 것 찾기
                //(전체 칸 수) - (바꿔야할 칸 수) = (첫 칸이 다른 색깔일 때 바꿔야할 칸 수)
                smallerNum = Math.min(count, (WIDTH_OF_CHESSBOARD * HEIGHT_OF_CHESSBOARD) - count);
                min = Math.min(min, smallerNum);
            }
        }
        System.out.println(min);
    }
}

어떻게 할 줄 모르겠어서 4중첩 for문을 갈겨버렸다.

 

 

(수정) st님 블로그 보고 따라치며 고친 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
     final static int SIZE_OF_CHESSBOARD = 8;
     public static boolean[][] chessBoard;
     public static int min = SIZE_OF_CHESSBOARD * SIZE_OF_CHESSBOARD; //64

     public static void countNeedPainting(int i, int j){
        int count = 0;
        boolean TF = chessBoard[i][j];
        for(int k=i; k<SIZE_OF_CHESSBOARD+i; k++){
            for(int l=j; l<SIZE_OF_CHESSBOARD+j; l++) {
                if(TF != chessBoard[k][l]){
                    count++;
                }
                TF = !TF;
            }
            TF = !TF;
        }
         count = Math.min(count, (SIZE_OF_CHESSBOARD * SIZE_OF_CHESSBOARD) - count);
         min = Math.min(min, count);
    }
    
    public static void main(String args[]) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int height = Integer.parseInt(st.nextToken());
        int width = Integer.parseInt(st.nextToken());
        chessBoard = new boolean[height][width];

        for(int i=0; i<height; i++){ //B이면 true , W이면 false 채우기
            String input = br.readLine();
            for(int j=0; j<width; j++){
                if(input.charAt(j) == 'B') chessBoard[i][j] = true;
                else chessBoard[i][j] = false;
            }
        }
        int numOfChessBoardInColumn = height-SIZE_OF_CHESSBOARD+1; //열에 들어갈 수 있는 8X8 체스보드 수
        int numOfChessBoardInRow = width-SIZE_OF_CHESSBOARD+1; //행에 들어갈 수 있는 8X8 체스보드 수
        int count = 0;
        for(int i=0; i<numOfChessBoardInColumn; i++){
            for(int j=0; j<numOfChessBoardInRow; j++){
                countNeedPainting(i, j);
            }
        }
        System.out.println(min);
    }

}

절차적으로 문제 푸는데에만 급급하다보니, 함수를 만드는게 어색하다. 객체지향 공부도 해야한다.

 

생각해보니 min값도 체스판 크기인 64인게 맞았다. N의 최댓값이 50이길래 2501로 해놨었다.

댓글