코딩테스트/분할 정복(Divide and Conquer)

[Java] 백준 2447번 : 별 찍기 - 10

sujin7837 2022. 3. 3. 01:10
반응형

문제

재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다.

크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.

***
* *
***

N이 3보다 클 경우, 크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴으로 둘러싼 형태이다. 예를 들어 크기 27의 패턴은 예제 출력 1과 같다.

입력

첫째 줄에 N이 주어진다. N은 3의 거듭제곱이다. 즉 어떤 정수 k에 대해 N=3k이며, 이때 1 ≤ k < 8이다.

출력

첫째 줄부터 N번째 줄까지 별을 출력한다.

예제 입력 1

27

예제 출력 1

***************************
* ** ** ** ** ** ** ** ** *
***************************
***   ******   ******   ***
* *   * ** *   * ** *   * *
***   ******   ******   ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
*********         *********
* ** ** *         * ** ** *
*********         *********
***   ***         ***   ***
* *   * *         * *   * *
***   ***         ***   ***
*********         *********
* ** ** *         * ** ** *
*********         *********
***************************
* ** ** ** ** ** ** ** ** *
***************************
***   ******   ******   ***
* *   * ** *   * ** *   * *
***   ******   ******   ***
***************************
* ** ** ** ** ** ** ** ** *
***************************

 

소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	private static BufferedReader bf;
	private static StringTokenizer st;
	
	private static int N;
	private static char [][] result;
	
	public static void main(String[] args) throws NumberFormatException, IOException {

		bf=new BufferedReader(new InputStreamReader(System.in));
		N=Integer.parseInt(bf.readLine());
		result=new char[N][N];
		
        for(int r=0;r<N;r++) {
			for(int c=0;c<N;c++) result[r][c]=' ';
		}
        
		divide(0,0,N);
		StringBuilder sb=new StringBuilder();
		for(char []r:result) {
			for(char c:r) sb.append(c);
			sb.append("\n");
		}
		System.out.println(sb);
	}

	public static void divide(int x, int y, int size) {
		if(size==1) {
			result[x][y]='*';
			return;
		}
		size/=3;
		for(int r=0;r<3;r++) {
			for(int c=0;c<3;c++) {
				if(r==1 && c==1) continue;
				divide(x+r*size, y+c*size, size);
			}
		}
	}
}

divide 메서드에서 return을 빼먹어서 자꾸 stackoverflow가 발생했었습니다. 이를 해결해주었는데도 계속 '틀렸습니다'가 나와서 답을 찾던 중, char 배열을 초기화해주지 않으면 공백이 아닌 \0이 들어간다는 것을 알게 되었습니다.

최종적으로 메서드 호출 전에 char 배열을 초기화주는 과정을 통해 해결할 수 있었습니다.

반응형