PS

백준 2448. 별 찍기 - 11

tose33 2021. 5. 28. 23:56

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

 

2448번: 별 찍기 - 11

첫째 줄에 N이 주어진다. N은 항상 3×2k 수이다. (3, 6, 12, 24, 48, ...) (0 ≤ k ≤ 10, k는 정수)

www.acmicpc.net

 

 

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

 

패턴을 보면 맨위 중앙을 원점이라고 했을때 

원점을 기준으로 크게 삼각형을 그리고,

원점에서 아래로 n/2, 왼쪽으로 n/2 지점에서 또 삼각형을 그리고,

원점에서 아래로 n/2, 오른쪽으로 n/2 지점에서 또 삼각형을 그린다.

 

그렇게 그린 작은 삼각형의 맨위 중앙을 또다시 기준으로 삼각형을 그리고

기준의 아래로 n/2, 왼쪽으로 n/2 지점에서 또 삼각형을 그리고,

기준의 아래로 n/2, 오른쪽으로 n/2 지점에서 또 삼각형을 그린다.

 

이렇게 반복해서 그리면 패턴이 완성된다. 

즉 재귀로 n값과, 삼각형을 그릴 기준이 되는 원점의 좌표를 넘겨주면서 계속 삼각형을 그린다.

 

#include <iostream>
using namespace std;

char stars[4000][8000];
int N;


void printStars(int n, int r, int c) {
    if(n==1) return;

    int row = r;
    int col = c;
    int row_len = n; // 행의 길이
    int col_len = n * 2; // 열의 길이

    // 우측하단으로 향하는 별
    // (r,c)에서부터 우측하단으로 이동하면서 별을 찍는다
    for(int i = 0; i < row_len; i++) {
        stars[row][col] = '*';
        row++; col++;
    }

    // 좌측하단으로 향하는 별
    // 다시 원점인 (r,c)로 돌아와서
    row = r;
    col = c;
    // (r, c)에서부터 좌측하단으로 이동하면서 별을 찍는다
    for(int i = 0; i < row_len; i++) {
        stars[row][col] = '*';
        row++; col--;
    }

    // 좌측하단으로 향하는 별을 찍으면서 한칸씩 더 갔기 때문에 한칸 되돌아간다
    row--; col++;
    // 좌측하단에서 우측하단으로 향하는 별
    int cnt = 0;
    for(int i = 0; i < col_len-1; i++) {
        stars[row][col] = '*';
        cnt++;
        col++;
        // 별을 다섯개 찍을때마다 공백이 하나 있으므로 별을 찍지 않도록 i를 1증가시켜준다
        if(cnt == 5) { col++; i++; cnt = 0; }
    }

    // 현재 큰 삼각형 중앙위 꼭짓점
    printStars(n/2, r, c);
    // 중앙위 꼭짓점에서 n/2 아래, n/2 왼쪽 지점
    printStars(n/2, r + (n/2), c - (n / 2));
    // 중앙위 꼭짓점에서 n/2 아래, n/2 오른쪽 지점
    printStars(n/2, r+ (n/2), c + (n / 2));

}

// 공백으로 초기화
void init() {
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N*2; j++) {
            stars[i][j] = ' ';
        }
    }
}

// 출력
void print() {
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N*2; j++) {
            cout << stars[i][j];
        }
        cout << '\n';
    }
}

int main() {
    cin >> N;

    init();
    // 첫 시작 좌표 (0, n-1)
    printStars(N, 0, N-1);
    print();
}