단계별로 풀어보기 > 재귀 > 별 찍기 - 10
https://www.acmicpc.net/problem/2447
3의 거듭제곱 N이 주어질 때, 크기 3의 패턴은 가운데의 공백이 있는 3 x 3 정사각형 모형이다.
N=3인 경우
***
* *
***
해당 모형을 가지고 N이 9일 경우 N이 3인 경우의 모형을 가지고 9 X 9 정사각형 모형을 만든다.(문제 참고)

가운데에 항상 공백이 발생한다는 것을 이용하여 2차원 배열을 이용하여 풀이한다.
시작 좌표 x,y 와 크기 N, 공백을 칠해야하는지 여부 blank를 받는 paintStar 메서드를 생성한다.
해당 메서드는 blank가 true 인 경우 시작 좌표로 부터 각각 x + N ,y + N 전까지의 범위는 모두 공백으로 칠한다.
또한 N이 1이어서 더 이상 3으로 나눠지지 않을 때는 해당 부위를 "*" 로 칠한다.
가장 중요한 부분인 N x N을 1/3하여 재귀적으로 부분을 나누는 방식이다.
입력받은 크기 N을 1/3을 하여 처음 시작 좌표 x,y 에 각각 +size를 더한 값을 paintStar 메서드를 재귀로 불러와서 실행시킨다. 이 때, count == 5(가운데 부분)은 blank를 true로 설정하고 paintStar 메서드를 불러온다.
import java.io.*;
public class 별_찍기_10 {
public static String arr[][];
public static void paintStar(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;
for(int i = x; i<x+N; i += size){
for(int j = y; j<y+N; j += size){
count++;
if(count == 5){
paintStar(i,j,size,true);
} else{
paintStar(i,j,size, false);
}
}
}
}
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());
arr = new String[N][N];
paintStar(0,0,N,false);
for(int i=0; i<N; i++){
for(int j =0; j<N; j++){
bw.write(arr[i][j]);
}
bw.write("\n");
}
bw.flush();
bw.close();
br.close();
}
}
Review
import java.io.*;
public class 별_찍기_10_review {
private static String arr[][];
public static void star(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;
for(int i = x; i<x+N; i+=size){
for(int j = y; j<y+N; j+=size){
count++;
if(count == 5){
star(i,j,size,true);
}else{
star(i,j,size,false);
}
}
}
}
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());
arr = new String[N][N];
star(0,0,N,false);
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
bw.write(arr[i][j]);
}
bw.write("\n");
}
bw.flush();
bw.close();
br.close();
}
}
가장 중요한 부분은 가장 큰 정사각형을 1/3로 나눠서 나눈 것을 또 1/3씩 재귀로 나누는 부분인 것이다. 처음에는 왜 x+N까지 인질 이해하기가 어려웠지만, 그림을 그려서 각각 1/3한 파트를 재귀로 불러온다는 것을 이해하니 문제를 이해할 수 있었다.
출처
https://st-lab.tistory.com/95
Review
star 메서드에 return을 넣지 않아서 재귀가 종료되지 않았었다.
재귀에서는 반드시 조건에 유의 하여 return을 해주자.


Review
