[백준] 2447

당당·2023년 5월 21일
0

백준

목록 보기
115/179

https://www.acmicpc.net/problem/2447

📔문제

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

***
* *
***

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


📝입력

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


📺출력

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


📝예제 입력 1

27

📺예제 출력 1

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

🔍출처

-문제를 만든 사람: baekjoon
-문제를 다시 작성한 사람: jh05013


🧮알고리즘 분류

  • 분할 정복
  • 재귀

📃소스 코드

import java.util.Scanner;

public class Code2447 {
    static int N;
    static char[][] stars;
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        N=sc.nextInt();

        stars=new char[N][N];

        star(0,0,N,false);

        StringBuilder answer=new StringBuilder();
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                answer.append(stars[i][j]);
            }
            answer.append("\n");
        }

        System.out.println(answer);
    }
    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++){
                    stars[i][j]=' ';
                }
            }
            return;
        }

        if(N==1){
            stars[x][y]='*';
            return;
        }

        int size=N/3;
        //각 블록은 이전 사이즈를 총 9개 들고있는거랑 마찬가지임
        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);
                }
            }
        }

    }

}


📰출력 결과


📂고찰

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

머리로는 무엇이 규칙이고, 어떤식으로 반복되는지 확실히 알 수 있었다.
하지만 코드로 짜는게 생각만큼 쉽지 않았다..

위의 블로그를 보았다. 다시 한 번 풀어볼 문제가 되었다!!

이전 블록 크기만큼을 반복하면서 만약 5번이 반복이 되면 공백이 입력될 차례이다.
char 2차원 배열을 선언해서 해결하였다.
먼저, N이 1이라면 *하나만 있는 것이다. 그리고 공백은 이 된다.

만약 N이 3인 것이 들어왔다고 치면 for문은 x (0)부터 x+3(3)까지, i는 1씩 증가한다. 그리고 y도 똑같으며 반복될때마다 count를 증가시킨다.
(몇번 반복됐는지 확인하기 위해서!)

즉, 이 알고리즘은 분할 정복을 이용한 것이다! N이 들어올때마다 N이 1이 될때까지로 쪼개면서 char 배열에 각각의 값을 저장하며 진짜 내가 생각한 이상적인 코드가 되는 것이다..

x+N을 해준 이유는 빈칸을 만들 때, N=9이면 그때 x값은 3일 것이고, 빈칸은 총 3칸씩이 되어야 하므로 (size는 3이니까) 3+3으로 총 3부터 6까지 3번 돌게 되는 것이다.

그리고 각각의 분할된 것들이 몇 번씩 반복해야되는지 정해주기도 한다!

profile
MySQL DBA 신입 지원

0개의 댓글