공부/백준

2447번: 별 찍기 - 10(백준 C++)

상연 2020. 10. 20. 21:52

목차

    2447번: 별 찍기 - 10 링크

    코드

    #include <iostream>
    using namespace std;
    
    char arr[2187][2187];
    
    void init(){
      for(int i=0; i<2187; i++){
        for(int j=0; j<2187; j++){
          arr[i][j] = ' ';
        }
      }
    }
    
    
    void solve(int n, int x, int y){
      if(n == 1) {
        arr[x][y] = '*';
      }
      else{
        for(int i=x; i<x+n; i+=n/3){
          for(int j=y; j<y+n; j+=n/3){
            if(i == (x + n/3) && j == (y + n/3)) continue;
            solve(n/3, i, j);
          }
        }
      }
    }
    int main(){
      init();
      int n;
      cin >> n;
      solve(n, 0, 0);
    
      for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
          cout << arr[i][j];
        }
        cout << "\n";
      }
    }
    

    사견

    재귀함수를 이용한 별 찍기 문제.

    입력

    우선 입력을 보자.
    입력 N은 3의 거듭제곱이 주어진다.

    N = 3^k 라고 할 때, k의 범위는 1 <= k < 8이다.

    그리고 주어진 문제에 따라 찍어야 하는 별의 범위는 N X N 사이즈이다.

    즉, 우선 기본적으로

    char arr[2187][2187];

    이라는 도화지를 준비하면 문제 풀이에 용이하다.
    ( 3^7 = 2187, 즉 주어질 수 있는 N에 따른 최대범위 배열)

    void init(){
      for(int i=0; i<2187; i++){
        for(int j=0; j<2187; j++){
          arr[i][j] = ' ';
        }
      }
    }

    이후 그 도화지의 모든 칸에 ' ' , 공백을 넣어준다.

    규칙

    재귀함수 문제를 풀 때에는 반복되는 규칙성을 찾아내는 것이 중요하다.

    이 문제 같은 경우에는

    주어진 N에 대해 이러한 구조를 가지고, 위 그림에서 보면 각 네모칸 안의 N이 3보다 크다면 그 안에서 또 위와같은 정사각형이 있는 형태이다.

    이러한 규칙에 따라 재귀함수로 N == 1일때 별을 찍어주는 형태로 코드를 짜면

    void solve(int n, int x, int y){
      if(n == 1) {
        arr[x][y] = '*';
      }
      else{
        for(int i=x; i<x+n; i+=n/3){
          for(int j=y; j<y+n; j+=n/3){
            if(i == (x + n/3) && j == (y + n/3)) continue;
            solve(n/3, i, j);
          }
        }
      }
    }

    이렇게 된다.

    재귀함수가 끝나면, 배열에 별이 다 찍혀있으므로, N의 크기에 맞춰서 출력해주면 된다.