Algorithm/Baekjoon
[백준] 25682: 체스판 다시 칠하기 2 - JAVA
Baspo8
2024. 5. 19. 04:13
https://www.acmicpc.net/problem/25682
풀이
M x N 사이즈의 보드가 주어지고, K x K 의 크기로 잘라 이 구역을 체스판 모양으로 만들어야한다. 뭔가 이 말을 이해하는데 오래걸렸다...
체스판은 흰색 검은색이 번갈아 나온다.
체스판의 첫 칸을 (0, 0)이라고 한다면, 첫칸이 흰색이면 격자의 행 + 격자의 열 번호를 더했을 때 짝수이면 흰색, 홀수이면 검은색이다.
첫칸이 검은색이면 마찬가지 방식으로 반대로 된다.
BW로 이루어진 보드를 입력받으면서 위의 규칙에 맞게 첫칸이 흰색인 배열, 첫칸이 검은색인 배열에 각각 넣었다.
이 배열에서 1이 의미하는 것은 격자의 색깔이 맞지 않아 새로 칠해야 한다는 의미이다.
잘 맞게 칠해져있는 것은 0으로 한다.
검은색, 흰색 각각 2차원 누적합 배열을 만들어주고,
K x K 크기에 맞게 잘라가면서 해당 구역에 몇 개를 새로 칠해야 하는지 구해주면 된다.
int cnt = sum[i + k - 1][j + k - 1] - sum[i - 1][j + k - 1] - sum[i + k - 1][j - 1] + sum[i - 1][j - 1];
sum 이차원배열에서 K x K 크기의 구역에 새로 칠해야 할 개수를 구하는 방법은 위와 같다.
메모리: 87060KB
시간: 500ms
언어: Java 11
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int[][] white = new int[n][m];
int[][] black = new int[n][m];
for (int i = 0; i < n; i++) {
String line = br.readLine();
for (int j = 0; j < m; j++) {
char color = line.charAt(j);
if ((i + j) % 2 == 0) {
white[i][j] = color == 'W' ? 0 : 1;
black[i][j] = color == 'B' ? 0 : 1;
} else {
white[i][j] = color == 'W' ? 1 : 0;
black[i][j] = color == 'B' ? 1 : 0;
}
}
}
int[][] sumWhite = new int[n + 1][m + 1];
int[][] sumBlack = new int[n + 1][m + 1];
for (int i = 1; i < n + 1; i++) {
for (int j = 1; j < m + 1; j++) {
sumWhite[i][j] = sumWhite[i - 1][j] + sumWhite[i][j - 1] - sumWhite[i - 1][j - 1] + white[i - 1][j - 1];
sumBlack[i][j] = sumBlack[i - 1][j] + sumBlack[i][j - 1] - sumBlack[i - 1][j - 1] + black[i - 1][j - 1];
}
}
int answer = Integer.MAX_VALUE;
for (int i = 1; i <= n - k + 1; i++) {
for (int j = 1; j <= m - k + 1; j++) {
int cntWhite = sumWhite[i + k - 1][j + k - 1] - sumWhite[i - 1][j + k - 1] - sumWhite[i + k - 1][j - 1]
+ sumWhite[i - 1][j - 1];
int cntBlack = sumBlack[i + k - 1][j + k - 1] - sumBlack[i - 1][j + k - 1] - sumBlack[i + k - 1][j - 1]
+ sumBlack[i - 1][j - 1];
answer = Math.min(answer, Math.min(cntWhite, cntBlack));
}
}
System.out.println(answer);
}
}