Algorithm/백준 알고리즘 풀이

[자바] 백준 2447번 별 찍기 - 10. 2021-07-27

최동훈1 2021. 7. 27. 16:39

1시간이 걸려서 해결했다.  이 문제의 핵심은 "반복문의 1회 연산시 증가하는 단위값" 을  점차적으로 3을 나누어서 1까지 재귀를 쓴 다음 단위값이 1이면 해당 좌표에 실질적인 별을 찍어주면 된다.

자세한 풀이는 코드에 주석으로 남겼다.

import java.util.Scanner;

public class Main {
    static char[][] arr;
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        StringBuilder sb=new StringBuilder();
       int N=s.nextInt();
       arr=new char[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                arr[i][j]=' ';//모든 배열 칸을 공백으로 채운다. 왜냐하면 아래의
                //재귀에서 각 배열의[1,1] 을 비워야 하기 때문이다.
                //여기서 배열 [1,1]이란 액면가 그대로의 좌표가 아니라
                //for문을 통해 한번 + 연산을 수행하는 단위 기준이다.
                //즉, 각 행과 열을 한칸씩 단위로 이동한 곳은 비워준다는 의미이다.
            }
        }
       recursive(0,0,N);
        //마지막에 행과 열 초기값을 0으로 주지 않아서 실수했다.
        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);


    }
    static void recursive(int ni,int nj,int N){
        /*
        처음에는 어떤 파라미터를 넣어야 할 지 막막했는데, 각 칸을 3의 배수로 나눠서
        그 3의 배수를 나눈 단위로 for문을 통해 재귀호출하면 된다.
         */
        if(N/3==1){
//여기서 N을 3으로 나누었을때 1이란 뜻은, 연산의 단위가 1이란 뜻이므로
            //파라미터로 넘어온 초깃값+3 까지 1이 증가하는 for문 연산을 진행한다.

            for(int i=ni;i<ni+3;i++){
                for (int j = nj; j < nj+3; j++) {
                    if(i==ni+1&&j==nj+1){
                        continue;
                    }
                    arr[i][j]='*';

                }
            }
            return;

        }


            int nextN=N/3;//이 문제에서 가장 핵심이다.
        //연산의 "단위" 를 지정하여서 반복문의 증가 단위로 쓰는 것이다.
            for (int i = ni; i < ni+nextN*3; i+=nextN) {
                //이 for 문의 조건도 핵심인데, 총 3번의 연산을 진행하게끔 만들려면
                // i값이 초깃값에서 연산의 단위가 3번 곱해진 값까지 더하는 것으로
                //범위를 설정해야 한다.
                for (int j = nj; j <nj+nextN*3; j+=nextN) {
                    if(i==ni+nextN&&j==nj+nextN){
                        continue;
                    }
                    recursive(i,j,nextN);
                    //1회 연산진행시 증가단위와 해당 초깃값을 넘겨서 재귀로 돌려준다.
                }

        }

    }

}

 

공부시간 1시간 

순공부시간 1시간.

 

오늘은 오전 9시 30분 부터 오후 3시까지 어르신 모시고 병원 입원수속 받는다고 공부를 거의 못했다. 그런데 돌아와서 1시간동안 정말 순도높은 공부를 한 것 같다. 오랜만에 이렇게 긴 시간 집중해서 알고리즘 문제를 완벽하게 해결해본거 같다. 이 문제는 내가 거의 1년전에 손도 못댔던 문제였는데, 다시 보니 완벽하게 해결했다. 나 자신이 자랑스럽고 대견하다. 내가 성장하고 있구나. 내가 꿈에 점점 다가가고 있구나. 이런 마음이 들었다. 행복했다.