https://www.acmicpc.net/problem/2448
문제를 처음 보면 단순 구현처럼 보이지만 실제로는 재귀 구조를 이해해야 풀리는 문제였다.
나도 처음에는 감이 잘 안 잡혀서 막히는 느낌이 있었는데 핵심은 삼각형을 어떻게 쪼개느냐였다.
이 문제는 높이 N의 큰 삼각형이 있다고 할 때, 이걸 한 번에 그리는 게 아니라 작은 삼각형 3개로 분할해서 생각해야 한다.
높이 N짜리 삼각형은 다음과 같이 구성된다.
- 위에 높이 N/2짜리 삼각형 1개
- 아래에 높이 N/2짜리 삼각형 2개 (왼쪽, 오른쪽)
즉 하나의 삼각형을 계속 절반으로 쪼개면서 그리는 구조다.
이걸 재귀로 표현하면 자연스럽게 해결된다.
좌표를 어떻게 잡느냐도 중요하다.
이 문제에서는 (x, y)를 삼각형의 꼭대기 좌표라고 정의한다.
처음 시작은 전체 삼각형의 꼭대기이므로
- 행: 0 (맨 위)
- 열: N - 1 (가운데)
즉 시작 호출은
이렇게 된다.
배열 크기도 헷갈리기 쉬운 부분인데,
삼각형의 밑변을 기준으로 생각하면 이해가 쉽다.
높이가 N일 때 아래로 한 줄 내려갈 때마다 좌우로 1칸씩 퍼지기 때문에
맨 아래 줄은
- 왼쪽으로 N - 1칸
- 오른쪽으로 N - 1칸
퍼진다.
그래서 전체 너비는
이 된다.
재귀 함수의 핵심은 다음과 같다.
- (x, y) : 삼각형의 꼭대기 좌표
- size : 삼각형의 높이
1. 종료 조건
높이가 3일 때는 더 쪼갤 수 없으므로 직접 별을 찍는다.
* *
*****
이걸 좌표 기준으로 찍어주면 된다.
2. 재귀 분할
높이가 3보다 크면, 삼각형을 3개로 나눈다.
- 위 삼각형: (x, y)
- 왼쪽 아래: (x + size/2, y - size/2)
- 오른쪽 아래: (x + size/2, y + size/2)
이렇게 각각 다시 draw를 호출한다.
전체 코드는 다음과 같다.
import java.io.*;
import java.util.*;
public class Main {
static int N;
static StringBuilder sb = new StringBuilder();
static char[][] stars;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
stars = new char[N][2 * N - 1];
for (int i = 0; i < N; i++) {
for (int j = 0; j < 2 * N - 1; j++) {
stars[i][j] = ' ';
}
}
draw(0, N - 1, N);
for (int i = 0; i < N; i++) {
sb.append(stars[i]).append('\n');
}
System.out.println(sb);
}
private static void draw(int r, int c, int size) {
if (size == 3) {
stars[r][c] = '*';
stars[r + 1][c - 1] = '*';
stars[r + 1][c + 1] = '*';
for (int i = -2; i <= 2; i++) {
stars[r + 2][c + i] = '*';
}
return;
}
int half = size / 2;
draw(r, c, half);
draw(r + half, c - half, half);
draw(r + half, c + half, half);
}
}
이 문제를 풀면서 느낀 건, 단순히 별을 찍는 문제가 아니라
큰 문제를 작은 문제로 나누는 방식을 연습하는 문제라는 점이었다.
처음에는 좌표가 헷갈리고 왜 이렇게 나누는지 감이 안 오는데
삼각형을 직접 그려보면서
- 꼭대기 기준으로 생각하기
- 좌우로 퍼지는 구조 이해하기
이 두 가지만 잡히면 훨씬 쉽게 접근할 수 있다.
비슷한 유형의 재귀 문제를 풀 때도 같은 방식으로 접근하면 도움이 된다.
'코딩테스트 > JAVA' 카테고리의 다른 글
| [백준 JAVA] 1629번: 곱셈 (0) | 2026.04.02 |
|---|---|
| [백준 JAVA] 5639번: 이진 검색 트리 (0) | 2026.04.02 |
| [백준 JAVA] 1967번: 트리의 지름 (0) | 2026.04.02 |
| [백준 JAVA] 1504번: 특정한 최단 경로 (0) | 2026.04.02 |
| [백준 JAVA] 1043번: 거짓말 (0) | 2026.03.30 |