Algorithm/[BOJ] - JAVA

[백준] 1018 : 체스판 다시 칠하기 JAVA 풀이

Codew 2022. 5. 24. 15:05

 

코딩 문제를 풀면서 내 문해력이 이렇게 부족했던가..라는 생각을 많이 한다.

문제가 요구하는 바가 뭔지 ㅜㅜ 잘 이해가 안된다.

이번 문제도 문제를 이해하는 것부터가 문제였다.

 

1. NxM 크기의 보드가 있다.

2. 이 보드에서 8x8 크기의 체스판을 만들 것이다.

3. 그 체스판을 만들기 위해 새로 칠해야 하는 칸의 개수가 최소일 때를 찾아야 한다.

-> 새로 칠해야 하는 칸의 개수는 체스판의 시작점인 맨 왼쪽 위 칸이

     흰색인 경우와 검은색인 경우에 따라 달라진다.

 

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

public class Main{
    // 입력되는 보드의 색깔을 기록하는 배열
	public static boolean[][] arr;
    public static void main(String[] args) throws IOException{
        // 한 줄을 입력받음
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 입력받은 한 줄을 " "를 기준으로 쪼갬
    	StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        // N과 M을 변수에 저장
    	int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        
        // NxM 배열 생성
        arr = new boolean[N][M];
        
        // 보드의 값을 배열에 넣어줘야 함
        for(int i=0;i<N;i++){
        // 한 줄을 읽음
        	String str = br.readLine();
            
            for(int j=0;j<M;j++){
            // 입력받은 보드의 칸이 검은색이면 true 흰색이면 false
            	if(str.charAt(j)=='B') arr[i][j] = true;
            	else arr[i][j] = false;
            }
        }
        
        // 새로 칠해야 하는 칸의 최솟값 저장하기 위한 변수
        int min = M*N+1;
        // 새로 칠해야 하는 칸의 수를 저장할 변수
        int cnt=0;
        
        // 체스판의 크기는 8x8이므로 반복문 조건을 저렇게 설정했음
        // 예를 들어 N = 8, M = 8이면 i=0, j=0일 때까지만 반복문이 실행됨
        // 8x8 짜리 보드로 만들 수 있는 체스판은 단 하나뿐이니까
        for(int i=0;i<N-7;i++) {
        	for(int j=0;j<M-7;j++) {
            
                // 새로 칠해야 하는 칸 수를 cnt에 저장
        		cnt = check(i,j);
                // 새로 칠해야 하는 칸수의 최솟값이 변경됐으면 min을 업데이트
        		min = Math.min(cnt, min);
        	}
        }
        // 새로 칠해야 하는 칸의 최솟값을 출력
        System.out.print(min);
    }
    public static int check(int x, int y) {
    
        // 체스판의 맨 왼쪽 맨 위 칸이 검정색일 때 새로 칠해야 하는 칸의 수
        int B=0;
        // 체스판의 맨 왼쪽 맨 위 칸이 흰색일 때 새로 칠해야 하는 칸의 수
        int W = 0;
        
        // 체스판의 크기는 8x8이니까 반복문의 조건을 이렇게 설정함
    	for(int i=x;i<x+8;i++) {
    		for(int j=y;j<y+8;j++) {
            // 시작점을 포함한 대각선의 칸은 전부 시작점의 색과 같아야 함
    			if((i+j)%2==0){
                // 그 칸의 값이 B이면 맨 왼쪽 맨 위가 W일 때는 새로 칠해줘야 하니 W++
                    if(arr[i][j]) W++;
                    // W이면 시작점이 B일 때 새로 칠해줘야 하니 B++
                    else B++;
                }
                else{
                    if(arr[i][j]) B++;
                    else W++;
                }
    		}
    	}
        // 시작점이 흰색일 때와 검은색일 때 중 칠해야 하는 칸의 수가 최소인 것을 반환
    	return Math.min(B,W);
    }
}