공부/알고리즘
[단계별로 풀어보기][python 3] 재귀 - 별찍기 - 10 (2447)
도리암
2022. 4. 30. 14:40
2447번: 별 찍기 - 10 (acmicpc.net)
2447번: 별 찍기 - 10
재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이
www.acmicpc.net
위와같은 패턴을 출력하는 문제다.
방안 1
각 빈칸은 다음과 같은 규칙이 존재한다.
x축과 y축의 값이 (n//3)%3 = 1 일 때 빈칸이 된다. (n은 3의 거듭제곱)
따라서 Boolean 배열을 이용해 빈칸을 구별한 뒤, 그에 따라 출력하면 된다.
def drawStar(a, m):
if m<1:
return a
for y in range(n):
for x in range(n):
if ((y//m)%3 == 1) and ((x//m)%3 == 1):
a[y][x] = False
return drawStar(a, m//3)
n = int(input())
first = []
for x in range(n):
first.append([True]*n)
done = drawStar(first, n)
for i in range(n):
for j in range(n):
if done[i][j] == True:
print('*', end="")
else:
print(' ', end="")
print("")
여기서 주의할 점은, first 배열을 선언할 때 [[True]*n]*n 을 하게 되면
[True]*n 이란 배열을 '참조하여' n개의 배열이 만들어지게 된다.
그렇게 되면 first[1][1] = False로 수정하면 모든 배열의 1번 인덱스가 바뀌므로 위의 방식을 사용해주자.
결과
시간복잡도가 O(n^2)라서 오래 걸린다. pypy3이 아니면 시간초과로 실패한다.
방안 2
처음부터 기본형인 배열 ['***', '* *', '***']을 만들어두고,
그 배열을 n번만큼 반복하여 array에 입력하는 방식을 취한다.
def star(n:int, x: list) -> list:
array = []
if n == 3:
return x
else:
for i in x:
array.append(i*3)
for i in x:
array.append(i+' '*len(i)+i)
for i in x:
array.append(i*3)
return star(n//3, array)
n = int(input())
first = ["***", "* *", "***"]
final = star(n, first)
for i in final:
print(i)
결과
시간복잡도가 O(n)으로 매우 빠른 시간내에 실행된다.