Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 프로그래밍 언어
- 플로이드-워셜
- Java
- 파이썬
- 자료구조
- 코테공부
- 1일1코테
- 티스토리챌린지
- 알고리즘
- 코드트리
- 자바
- 운영체제
- 연결 리스트
- 코딩테스트준비
- 99클럽
- 인접 행렬
- 코딩테스트사이트추천
- 자바스크립트
- 항해99
- 오블완
- 개발자취업
- 프로그래머스
- 코딩테스트
- 개발자루틴
- til
- 웹
- 갭체크
- 데이터베이스
- C
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
Archives
- Today
- Total
와드의 블로그
1018번: 체스판 다시 칠하기 본문
문제
M×N 크기의 보드가 주어집니다. 어떤 정사각형은 검은색('B')으로 칠해져 있고, 나머지는 흰색('W')으로 칠해져 있습니다. 이 보드를 잘라서 8×8 크기의 체스판으로 만들려고 합니다. 체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 합니다. (즉, 인접한 두 칸은 다른 색상이어야 합니다.) 8×8 크기로 자를 수 있는 모든 위치에 대해 체스판 패턴으로 다시 칠해야 하는 정사각형의 최소 개수를 구하는 프로그램을 작성하는 문제입니다.
- 입력: 첫째 줄에 N과 M이 주어집니다. (8 ≤ N, M ≤ 50) 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어집니다.
- 출력: 첫째 줄에 다시 칠해야 하는 정사각형 개수의 최솟값을 출력합니다.
링크: https://www.acmicpc.net/problem/1018
풀이: 좌표의 홀짝성(Parity)을 활용한 완전 탐색
보드의 크기가 최대 50×50이므로, 가능한 모든 8×8 체스판의 시작점을 순회하며 칠해야 하는 개수를 세는 브루트포스 방식으로 해결할 수 있습니다.
- 시작점 순회: 8×8 크기를 확보해야 하므로, 시작점의 행 i는 0부터 N-8까지, 열 j는 0부터 M-8까지 순회합니다.
- 좌표의 홀짝성(Parity) 활용: 정상적인 체스판은 행 좌표와 열 좌표의 합이 짝수인 칸들은 모두 같은 색이고, 홀수인 칸들도 모두 같은 색입니다.
- 탐색 중인 보드의 절대 좌표는 (y + i, x + j)입니다.
- 이 두 좌표의 합인 (y + x + i + j)가 짝수일 때 'B'가 오고, 홀수일 때 'W'가 오는 패턴 하나를 기준으로 잡고, 이에 어긋나는 칸의 개수(cnt)를 셉니다.
- 반대 패턴 계산 (64 - cnt): 8×8 체스판은 총 64칸입니다. 만약 (0,0)이 'B'인 패턴으로 칠할 때 cnt개의 칸을 다시 칠해야 한다면, (0,0)이 'W'인 반대 패턴으로 칠할 때는 정확히 나머지 칸들인 64 - cnt개만 다시 칠하면 됩니다.
- 최솟값 갱신: 하나의 8×8 구간을 탐색할 때마다 Math.min(cnt, 64 - cnt)를 통해 두 체스판 패턴 중 더 적게 칠하는 값을 구하고, 이를 전체 최솟값 ans와 비교하여 갱신합니다.
코드
import java.io.*;
import java.util.*;
public class Main {
static int n, m;
static char[][] a;
static int ans = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
a = new char[n][m];
for (int i = 0; i < n; i++) {
a[i] = br.readLine().toCharArray();
}
// 8x8 크기로 자를 수 있는 모든 시작점 탐색
for (int i = 0; i < n - 7; i++) {
for (int j = 0; j < m - 7; j++) {
checkBoard(i, j);
}
}
bw.write(ans + "");
bw.flush();
}
static void checkBoard(int y, int x) {
int cnt = 0;
// 시작점 (y, x)를 기준으로 8x8 영역 탐색
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
// 좌표 합의 홀짝성으로 번갈아 나타나는 패턴 검사
if ((i + j + y + x) % 2 == 0 && a[i + y][j + x] != 'B')
cnt++;
else if ((i + j + y + x) % 2 == 1 && a[i + y][j + x] != 'W')
cnt++;
}
}
// (현재 패턴 기준 칠하는 횟수) vs (반대 패턴 기준 칠하는 횟수) 중 최솟값으로 갱신
ans = Math.min(ans, Math.min(cnt, 64 - cnt));
}
}
알고리즘 분류
브루트포스 알고리즘 (Brute Force)
'PS > B.O.J' 카테고리의 다른 글
| 16637번: 괄호 추가하기 (0) | 2026.04.06 |
|---|---|
| 1080번: 행렬 (0) | 2026.04.06 |
| 2792번: 보석 상자 (0) | 2026.04.02 |
| 6236번: 용돈 관리 (0) | 2026.04.02 |
| 14627번: 파닭파닭 (0) | 2026.04.02 |