https://www.acmicpc.net/problem/2447
2447번: 별 찍기 - 10
재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이
www.acmicpc.net
문제
// 입력
27
// 출력
***************************
* ** ** ** ** ** ** ** ** *
***************************
*** ****** ****** ***
* * * ** * * ** * * *
*** ****** ****** ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
********* *********
* ** ** * * ** ** *
********* *********
*** *** *** ***
* * * * * * * *
*** *** *** ***
********* *********
* ** ** * * ** ** *
********* *********
***************************
* ** ** ** ** ** ** ** ** *
***************************
*** ****** ****** ***
* * * ** * * ** * * *
*** ****** ****** ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
문제 풀이
- 분할 정복(Divide and Conquer) 와 재귀 함수 문제이다.
- 분할 정복이란?
Divide and Conquer , 그대로 해결할 수 없는 문제를 작은 문제로 나누어(Divide) 해결하는 방법, 알고리즘이다. - 푼 방법
1) 별을 그릴 2차원 배열 arr[][]를 선언한다.
2) 분할을 어떻게 해서 문제를 풀어야하는가?
힌트1) 크기 3의 경우, 패턴을 생각해보자. [0][0], [0][1], [0][2], [1][0], [1][1] ... 의 순서로 1,2,3,4,5, ... 를 한다면 blank가 되는 칸은 5번째 칸이다. 이걸 확장하여서 생각해야 된다.
힌트2) 크기가 3ⁿ인 경우, 패턴을 생각해보자. [0][3ⁿ⁻¹] , [0][2 * 3ⁿ⁻¹], [0][3ⁿ], ... 의 순서로 1,2,3,4,5... 를 한다면 blank가 되는 칸은 5번째 칸이다.
3) 힌트1)과 힌트2)를 합쳐서 생각해보자.
힌트2)의 3ⁿ을 3으로 계속 나누어갈 경우, 1이 되는 순간이 존재한다. 즉, 재귀를 했을 때, base case가 되는 경우가 존재한다.
4) 크기가 3ⁿ인 경우는 너무 크다. 1,2,3,4,5,... 구역을 나누고 (Divide), 그 구역을 다시 나누고(Recursion)를 반복하면 결국 base case에 도달할 수 있고, base case는 '*'를 리턴하면 된다.
JAVA code
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class baekjoon2447 {
static void star(char[][] arr, int x, int y, int N, boolean blank) {
// 공백칸 일 경우
if (blank) {
for (int i = x; i < x + N; i++) {
for (int j = y; j < y + N; j++) {
arr[i][j] = ' ';
}
}
return;
}
if (N == 1) {
arr[x][y] = '*';
return;
}
int size = N / 3;
int count = 0;
// x와 y를 size만큼 더하는게 포인트
for (int i = x; i < x + N; i += size) {
for (int j = y; j < y + N; j += size) {
count++; // 다섯번째 구역을 판별하기 위해서
// 재귀
if (count == 5) {
star(arr, i, j, size, true);
} else {
star(arr, i, j, size, false);
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
char[][] arr = new char[N][N];
star(arr, 0, 0, N, false);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
sb.append(arr[i][j]);
}
sb.append('\n');
}
System.out.println(sb);
}
}
정리
https://st-lab.tistory.com/95?category=852877 를 보면서 이해했고, 사진의 출처도 여기입니다.
[백준] 2447번 : 별 찍기 - 10 - JAVA [자바]
www.acmicpc.net/problem/2447 2447번: 별 찍기 - 10 재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백..
st-lab.tistory.com
Divide And Conquer의 첫 풀이라 감이 오지 않아, 블로그를 정말 많이 참고하였다.
매우매우 설명이 잘되어있으니 제 정리글로 감이 오지 않는다면 꼭 한번 보길 바란다.
'백준 문제풀이' 카테고리의 다른 글
[백준] 17478번 재귀함수가 뭔가요? - 재귀(5) [JAVA] (0) | 2022.09.29 |
---|---|
[백준] 11729번 하노이 탑 이동순서 - 재귀(4) [JAVA] (1) | 2022.09.29 |
[백준] 피보나치 수 5 - 재귀(2) [JAVA] (0) | 2022.09.27 |
[백준] 10872번 팩토리얼 - 재귀(1) [JAVA] (0) | 2022.09.27 |
[백준] 2164번 카드2 [JAVA] (0) | 2022.09.14 |