2 minute read

1.

  • 출력 예제를 보고 별 찍는 규칙을 유추하여 별을 찍어 보자.

입력

  • 첫 번째 줄에는 정수 N (0 ≤ N ≤ 10)이 주어진다.

출력

  • 별 찍는 규칙에 따라 별을 출력한다.

  • 각 줄 끝에는 필요없는 공백을 출력하지 않는다.

입력 예제 1

0

출력 예제 1

*

입력 예제 2

1

출력 예제 2

**
*

입력 예제 3

2

출력 예제 3

****
* *
**
*

입력 예제 4

3

출력 예제 4

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

풀이

import sys

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

s = [['' for x in range(0, 1 << N)] for x in range(0, 1 << N)]


def print_ignite(n):
    m = 1 << n
    for i in range(0, m):
        for j in range(0, m - i):
            print(s[i][j], end='')
            if s[i][j] == '':
                print(' ',end='')
        print('')


def ignite(N, row, col):
    if N == 0:
        s[row][col] = '*'
        return

    else:
        ignite(N - 1, row, col)
        ignite(N - 1, row + (1 << (N - 1)), col)
        ignite(N - 1, row, col + (1 << (N - 1)))


ignite(N, 0, 0)

print_ignite(N)

채점 결과

  • 정답

리뷰

  • 출력 예제 결과를 보고, (x-1)번째 도형을 역삼각형으로 배치하면 되는 문제다! 라고 생각하고, 점화식을 세워보았다.

    • 하지만 결과물을 ‘출력’해야 한다는 점 때문에 str형식만 고집했고, 문제에 손조차 댈수 없었다.
  • 구글링을 통해 다음과 같은 접근법만 파악후, 다시 도전했다.
    • 2차원 배열을 사용하여 저장 후 출력.
    • (출력예제 2)의 도형이 반복되는것으로 생각할것.
    • (출력예제 2)의 도형은 (0,0), (1,0), (0,1)로 구성되어있다.
  • 첫번째 난관은 2차원 배열의 형성이었다.

    • 버그인지 모르겠으나, 2차원 배열의 형성을 위해 [[]] * N과 같이 리스트의 곱셈을 통해 리스트를 형성하는 경우, (0,0)에만 값을 집어넣어도 (1,0),(2,0)...등에 값이 들어가는 현상을 확인할수 있었다.

      • 추측컨대, 첫줄을 곱해서 리스트를 동적으로 생성하는 과정에서 얕은 복사가 발생해서 첫줄의 데이터를 그대로 복사해오는것이라 생각된다.

      • 이러한 심증을 굳혀주는 문서를 찾을수 있었다.

        • 얕은 복사와 깊은 복사
        • list는 mutable한 객체로서, list a를 b = a와 같은 방식으로 할당할 경우, a의 요소가 변할시 b의 요소 역시 같이 변경되는것을 확인할수 있다.
    • 해당 이슈로 인해 list comprehension을 통해 이중 배열을 생성해주었다.

      • 겸사겸사 shift 연산에도 익숙해질겸, pow연산(**) 대신 shift연산으로 배열의 크기를 지정해주었다.

      • shift연산

        • 비트 단위 연산.
        • 빠른 연산속도가 장점.
        • <<를 통해 비트를 왼쪽으로 밀어준다($2^n$을 곱해주는 효과)
        • >>를 통해 비트를 오른쪽으로 밀어준다($1/2^n$을 곱해주는 효과)
        • 2의 거듭제곱에 관련되었을때 사용하면 시간을 크게 아낄수 있다.
  • 출력 예제들을 손으로 그려가며, N=1일때의 도형이 어디서 시작되는지의 좌표를 인식했고, 그것을 점화식(=재귀함수)으로 옮겼다.

  • 이중배열에 담긴 데이터를 출력한다.

    • 이때, 전체적인 틀은 역삼각형 모양 + 부가적인 공백은 발생하면 안되므로, 이중반복문을 살짝 커스터마이징 해준다.

    • Python의 print문은 기본 옵션에 다음줄로 넘기는것이 포함되어 있으므로, print문의 종료 후 줄넘김을 막기위해 end=''와 같이 지정해주었다.

    • 공백인 데이터가 나왔을때, 한칸 공백을 주기위해 조건을 달아주고, 한줄의 출력이 끝날때마다 줄넘김을 위한 빈 print문을 사용해주었다.