백준
백준 2447번 별찍기-10 어떻게 풀었나. 재귀함수 사용. 파이썬
kimbro6
2023. 1. 15. 00:01
- 푼 방법
우선 재귀함수(f(n))를 사용해서 문제를 풀기로 한다.
재귀함수 f(n) 에서는 총 n*n 을 출력한다.
그 출력을 9등분 하여 가운데 부분은 n//3 * n//3 크기의 " " (빈 문자열)을 출력한다.
그다음, 가운데 부분의 주변 8부분은 f(n//3)을 출력한다.
만약에 n == 3이라면 """***\n* *\n***"""을 출력한다.
처음에는 재귀함수 안에서 바로 별을 프린트를 해 주려 했으나, 그렇게 하면 f(3)을 여러번 출력할때 옆으로 계속해서 출력 할 수 없었다.
그러므로 이차원 배열(ans)에 저장하여 .join()함수로 출력해 준다.
********* * * ** * ********* *** *** * * * * *** *** ********* * ** ** * ********* |
위를 출력하려고 할때, 별 ********* 이 출력 안되고
*** * * *** *** * * *** |
이런식으로 출력됨
이제 재귀함수의 기본 틀은 잡았다. 그런데 실행을 해 보니, 출력 결과가 이상했다.
n=27일때)
********* * * ** * ********* *** *** * * * * *** *** ********* * ** ** * ********* (제대로 출력됨) |
(빈칸) | (빈칸) |
(빈칸) | _________ _________ _________ _________ (" " 출력됨) _________ _________ _________ _________ |
(빈칸) |
(빈칸) | (빈칸) | (빈칸) |
코드를 다시 보니
"그다음, 가운데 부분의 주변 8부분은 f(n//3)을 출력한다."에서 8부분을 제대로 설정해 주지 않았다.
그래서 재귀함수에 별을 찍을 좌표를 추가로 전달했다.
f(n) ---> f(n, x, y)
그다음 코드로 구현했다.
- 좋았던점
- 재귀함수의 개념을 예전에 들었던 적이 있어서 재대로 구현할 수 있었다.
- 재귀함수 안에서 바로 프린트를 하면 안된다는것을 미리 알고 계획할때 수정했다.
- 고치면 좋을 부분
- 계획을 해 놓고 재대로 구현하지 않았다.
코드
import sys
N = int(sys.stdin.readline())
ans = [[0]*N for _ in range(N)]
def f(N, x, y):
n = N//3
if N == 3:
for i in range(3):
for j in range(3):
if i == 1 and j == 1:
ans[x+i][y+j] = " "
else:
ans[x+i][y+j] = "*"
else:
for i in range(n):
for j in range(n):
ans[n+i+x][n+j+y] = " "
for o in [0, n, 2*n]:
for k in [0, n, 2*n]:
if o != n or k != n:
f(n, o+x, k+y)
f(N, 0, 0)
for a in ans:
print("".join(a))