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
- 티스토리챌린지
- 인접 행렬
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- C
- 1일1코테
- 웹
- 파이썬
- 프로그래밍 언어
- til
- 99클럽
- 코테공부
- 자료구조
- 코딩테스트
- Java
- 자바스크립트
- 자바
- 코딩테스트사이트추천
- 코드트리
- 데이터베이스
- 오블완
- 코딩테스트준비
- 연결 리스트
- 갭체크
- 운영체제
- 플로이드-워셜
- 개발자루틴
- 항해99
- 개발자취업
- 프로그래머스
- 알고리즘
Archives
- Today
- Total
와드의 블로그
1992번: 쿼드트리 본문
문제
흑백 영상을 압축하여 표현하는 데이터 구조로 쿼드 트리(Quad Tree)가 있습니다. 주어진 영상이 모두 0으로만 되어 있으면 압축 결과는 "0"이 되고, 모두 1로만 되어 있으면 압축 결과는 "1"이 됩니다. 만약 0과 1이 섞여 있으면, 영상을 4개의 영역으로 나누어 압축하게 되며, 이 4개의 영역을 압축한 결과를 괄호 안에 묶어서 표현합니다. N × N 크기의 영상이 주어질 때, 이 영상을 압축한 결과를 출력하는 문제입니다.
- 입력: 첫째 줄에 영상의 크기 N (N은 1, 2, 4, 8, 16, 32, 64 중 하나)이 주어집니다. 둘째 줄부터 N개의 줄에 걸쳐 길이가 N인 0과 1로 이루어진 문자열이 주어집니다.
- 출력: 영상을 압축한 결과를 출력합니다.
링크: https://www.acmicpc.net/problem/1992
풀이
영역을 4등분으로 나누며 재귀적으로 탐색하는 전형적인 분할 정복(Divide and Conquer) 문제입니다.
- 영역 일치 확인: 현재 탐색 중인 영역(크기 n, 시작 좌표 y, x) 내의 모든 픽셀 값이 첫 번째 픽셀 값(tmp)과 일치하는지 이중 반복문을 통해 검사합니다.
- 모두 일치하는 경우 (기저 조건): 영역 내의 모든 픽셀이 같다면 더 이상 분할할 필요가 없으므로 해당 픽셀 값(tmp)을 문자열로 반환합니다.
- 불일치하는 경우 (분할 및 재귀 호출): 영역 내에 0과 1이 섞여 있다면, 압축이 불가능하므로 괄호 (를 열고 영역을 4등분(크기 n / 2)하여 각각 문제에서 요구하는 순서대로 재귀 호출합니다.
- 왼쪽 위: go(y, x, n / 2)
- 오른쪽 위: go(y, x + n / 2, n / 2)
- 왼쪽 아래: go(y + n / 2, x, n / 2)
- 오른쪽 아래: go(y + n / 2, x + n / 2, n / 2)
- 재귀 호출이 끝난 후에는 괄호 )를 닫아 묶어준 문자열을 반환합니다.
코드
import java.io.*;
public class Main {
static char[][] a;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
a = new char[n][n];
// 입력 최적화: 한 줄을 통째로 읽어 문자 배열로 변환하므로 단일 반복문 사용
for (int i = 0; i < n; i++) {
a[i] = br.readLine().toCharArray();
}
bw.write(go(0, 0, n));
bw.flush();
bw.close();
br.close();
}
static String go(int y, int x, int n) {
char tmp = a[y][x];
for (int i = y; i < y + n; i++) {
for (int j = x; j < x + n; j++) {
// 영역 내에 하나라도 다른 값이 있다면 4등분하여 분할 정복
if (tmp != a[i][j]) {
String ret = "(";
ret += go(y, x, n / 2); // 왼쪽 위
ret += go(y, x + n / 2, n / 2); // 오른쪽 위
ret += go(y + n / 2, x, n / 2); // 왼쪽 아래
ret += go(y + n / 2, x + n / 2, n / 2); // 오른쪽 아래
ret += ")";
return ret;
}
}
}
// 영역 내의 모든 값이 같다면 해당 값 반환
return String.valueOf(tmp);
}
}
알고리즘 분류
분할 정복 (Divide and Conquer), 재귀 (Recursion)
'PS > B.O.J' 카테고리의 다른 글
| 2910번: 빈도 정렬 (0) | 2026.03.22 |
|---|---|
| 2828번: 사과 담기 게임 (1) | 2026.03.22 |
| 2583번: 영역 구하기 (0) | 2026.03.21 |
| 2468번: 안전 영역 (0) | 2026.03.21 |
| 1012번: 유기농 배추 (0) | 2026.03.21 |