문제
재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다.
크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.
***
* *
***
N이 3보다 클 경우, 크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴으로 둘러싼 형태이다. 예를 들어 크기 27의 패턴은 예제 출력 1과 같다.
입력
첫째 줄에 N이 주어진다. N은 3의 거듭제곱이다. 즉 어떤 정수 k에 대해 N=3k이며, 이때 1 ≤ k < 8이다.
출력
첫째 줄부터 N번째 줄까지 별을 출력한다.
예제 입력 1
27
예제 출력 1
***************************
* ** ** ** ** ** ** ** ** *
***************************
*** ****** ****** ***
* * * ** * * ** * * *
*** ****** ****** ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
********* *********
* ** ** * * ** ** *
********* *********
*** *** *** ***
* * * * * * * *
*** *** *** ***
********* *********
* ** ** * * ** ** *
********* *********
***************************
* ** ** ** ** ** ** ** ** *
***************************
*** ****** ****** ***
* * * ** * * ** * * *
*** ****** ****** ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
나의 풀이
개인적으로 정해놓은 풀이 시간을 초과하여 아이디어를 코드로 구현하는 데는 실패
아이디어를 생각할 때 부터 어떤 방식으로 구현할 지 고민하는 것이 필요
O(0) | O(1) | O(2) |
O(3) | X(4) | O(5) |
O(6) | O(7) | O(8) |
아이디어
- $n$에서의 패턴은 $n//3$ 패턴이 3x3 형태(가운데만 비움)로 반복되면서 형성
- 이때 $n//3$ 패턴은 $n$에서 항상 좌측 상단(0,0)에 위치
- $n//3$의 패턴을 좌측 상단부터 차례로 반복시키면 $n$에서의 패턴 완성
동일한 아이디어로 구현된 풀이
- 별을 찍을 Map을 미리 nested list로 생성
- 생성된 Map의 1은 *, 0은 공백으로 출력
- $n//3$의 패턴을 복사할 때 $k$라는 작은 행 단위로 나눠서 생각
# 별 찍는 재귀 함수
def draw_star(n) :
global Map
if n == 3 :
Map[0][:3] = Map[2][:3] = [1]*3
Map[1][:3] = [1, 0, 1]
return
a = n//3
draw_star(n//3)
for i in range(3) :
for j in range(3) :
if i == 1 and j == 1 :
continue
for k in range(a) :
Map[a*i+k][a*j:a*(j+1)] = Map[k][:a] # 핵심 아이디어
N = int(input())
# 메인 데이터 선언
Map = [[0 for i in range(N)] for i in range(N)]
draw_star(N)
for i in Map :
for j in i :
if j :
print('*', end = '')
else :
print(' ', end = '')
print()