[백준] #2448 별찍기 - 11(python)

수영·2022년 10월 1일

백준

목록 보기
68/117
post-thumbnail

📌문제

예제를 보고 규칙을 유추한 뒤에 별을 찍어 보세요.

입력

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

출력

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

예제 입력

24

예제 출력

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

백준 2448번 문제

💡Idea

예제 출력을 자세히 보면, 별⭐로 이루어진 삼각형들이 각 삼각형의 양쪽 꼭짓점에 그대로 복사되어 있는 것을 알 수 있습니다.

파란색 부분의 별 삼각형에서 시작하여 노란색, 초록색의 순서로 가운데 삼각형이 양 옆으로 복사됩니다.

즉, 현재까지 그려진 별 삼각형을 자신의 양 옆 아래로 그대로 그리면서 별 삼각형의 크기를 키워나가는 것입니다.

💻코드1

  • ⏰ 시간 : 3044 ms / 메모리 : 189180 KB
import sys

N = int(sys.stdin.readline())

def place_star(arr, row): # 별 삼각형을 양 옆 아래로 복사해주는 함수
    if row == 0: # 별을 처음 그리는 경우 1 - 2 - 5 순으로 별을 그림
        mid = N - 1 # 가운데 위치
        arr[row][mid] = '*' # 첫번째 줄 별 그림
        arr[row + 1][mid - 1] = '*' # 두 번째 줄 왼쪽 별 그림
        arr[row + 1][mid + 1] = '*' # 두 번째 줄 오른쪽 별 그림
        for i in range(5): # 세 번째 줄 별 그림
            arr[row + 2][mid - 2 + i] = '*' # 왼쪽부터 차례로 별 그림

    if row >= N: return arr # 별을 다 그린 경우
    for i in range(row): # 한 줄씩 별 그림
        for j in range(N - row, N - 1 + row): # 왼쪽에서부터 별 그림 
            arr[row + i][j - row] = arr[i][j] # 왼쪽 아래로 별 복사
            arr[row + i][j + row] = arr[i][j] # 오른쪽 아래로 별 복사
    place_star(arr, 3 if row == 0 else row * 2) # 다음 별 삼각형 복사

star_arr = [[' ' for _ in range(2 * N)] for _ in range(N)]
place_star(star_arr, 0)

for i in range(N):
    print(''.join(star_arr[i]))

📝코드 설명1

함수 place_starrow는 다음으로 그려야 하는 줄을 의미합니다.

place_star에서는 들어온 row에 맞추어 현재까지 그려진 row - 1까지의 별 삼각형을 row ~ row + (row - 1)의 양 옆에 그대로 복사해줍니다.

별을 다 복사하면, 다음으로 그려야 하는 줄을 place_star에 넣어줍니다.

그렇게 별을 다 복사하면 함수는 종료합니다.

💻코드2

  • ⏰ 시간 : 884 ms / 메모리 : 177476 KB
import sys
input = sys.stdin.readline

n = int(input())

stars = [[' ']*2*n for _ in range(n)]

def recursion(i, j, size): # 별 삼각형을 반복하여 3등분하는 재귀 함수
    if size == 3: # 3줄짜리 별 삼각형가지 분할된 경우 별 그리기
        stars[i][j] = '*'
        stars[i + 1][j - 1] = stars[i + 1][j + 1] = "*"
        for k in range(-2, 3):
            stars[i + 2][j - k] = "*"
    
    else:
        newSize = size//2
        recursion(i, j, newSize) # 가운데 위 별 삼각형
        recursion(i + newSize, j - newSize, newSize) # 왼쪽 아래 별 삼각형
        recursion(i + newSize, j + newSize, newSize) # 오른쪽 아래 별 삼각형

recursion(0, n - 1, n)
for star in stars:
    print("".join(star))

📝코드 설명2

3044 ms의 시간이 걸렸던 앞의 코드보다 훨씬 적은 시간이 걸리는 코드를 발견해서 정리해봅니다!

이 코드는 전체 별 삼각형에서 시작해서, 계속해서 삼분할해나가는 재귀 함수를 구현하였습니다.

예제를 확인해보면, 각 별 삼각형은 가운데 위의 별 삼각형 하나, 아래 왼쪽 별 삼각형 하나, 아래 오른쪽 별 삼각형 하나의 3등분으로 구분되는 것을 확인할 수 있습니다.

따라서, 1 - 2 - 5의 별로 구성된 가장 작은 별 삼각형이 나올 때까지 계속해서 분할 한 뒤, 가장 작은 별 삼각형인 경우에는 별을 그려주는 식의 해결 방안 입니다.

Reference

https://ku-hug.tistory.com/149

profile
하고 싶은 건 그냥 죽도록 합니다

0개의 댓글