본문 바로가기

[BOJ] - JAVA

[백준] 2447 : 별 찍기 - 10 JAVA 풀이

 

이번 문제는 규칙이 있다는 건 알겠는데 코드로 어떻게 구현해야 하는지 감이 안와서 정말 어려웠다.

그래서 이 블로그의 포스트를 보고 이해하려고 노력해봤다.

https://st-lab.tistory.com/95

 

[백준] 2447번 : 별 찍기 - 10 - JAVA [자바]

www.acmicpc.net/problem/2447 2447번: 별 찍기 - 10 재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백..

st-lab.tistory.com

출력 예제를 잘 보면 하나의 블럭을 9등분으로 나눌 수가 있다.

그리고 나눠진 한 조각은 * * * * 공백 * * * * 이렇게 구성되어있다.

이것을 재귀로 구현해서 2차원 배열에 별이나 공백 값을 저장하면 된다.

 

이걸 재귀로 표현하는 방법은 이렇다.

 

N = 27일 때에는 한 블럭의 길이가 9인 9개의 블럭으로 나눌 수 있다.

그리고 9개의 블럭 중 공백인 블럭(다섯번째 블럭)이라면 공백으로 채우고,

공백이 아닌 블럭이라면 다시 재귀 호출을 한다.

 

그럼 N = 9가 되고, 그 블럭은 한 블럭의 길이가 3인 9개의 블럭으로 나눌 수 있다.

마찬가지로 9개의 블럭 중 공백인 블럭(다섯번째 블럭)이라면 공백으로 채우고

공백이 아니라면 다시 재귀 호출을 한다.

 

다음은 N = 3일 때인데 위와 같은 방식을 반복하면

N = 1인 순간이 오는데 이때는 더 쪼갤 수가 없기 때문에,

해당 배열의 값을 공백이나 *로 채우면 된다.

 

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
public class Main{
	public static char[][] arr;
    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 char[N][N];
        
        star(0, 0, N, false);
        
        /*
        	BufferedWriter는 자동으로 개행되지 않기 때문에 개행문자도 따로 추가해줘야 함
            버퍼를 다 사용했으면 flush()로 비우고 close()로 닫아줘야 함
        */
        
        for(int i=0;i<N;i++) {
        	bw.write(arr[i]);
        	bw.write("\n"); 
        }
        bw.flush();
        bw.close();
        
    }
    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;
    	}
    	/*
        	한 블럭을 9칸으로 나눴을 때 한 칸의 길이를 의미하는 size
            9개의 칸에서 다섯 번째 칸은 공백 구간인데,
            공백 구간인지 체크하기 위한 cnt
        */
    	int size = n/3;
    	int cnt = 0;
        /*
        	(x, y)에서 
            i와 j를 size만큼 증가시키는 건 다음 칸으로 넘어가기 위해서
            i<x+n-1, j<x+n-1까지 반복하는 건 한 블럭을 넘어가지 않기 위해서
        */
    	for(int i=x;i<x+n;i+=size) {
    		for(int j=y;j<y+n;j+=size) {
    			cnt++;
    			if(cnt==5) {
                /*
        		공백 구간이라면 blank를 true로
        		*/
    				star(i,j,size,true);
    			}
    			else {
    				star(i,j,size,false);
    			}
    		}
    	}
    }
}