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);
}
}