해당 게시글에서는 [백준] 2447 별 찍기 - 10 문제를 해설하고 Python
을 이용하여 풀고자 한다.
💡 문제 풀이
2447번 문제는 별 찍기 문제이다.
처음에 문제를 읽었을 때 단번에 이해가 되지 않았다. 지문과 예제를 동시에 보며 조금 고민하고 나서야 문제가 이해됐다.
단계별로 풀어보기 카테고리를 통해서 들어왔기 때문에 해당 문제가 재귀(recursion)
와 관련된 문제인 걸 알고 있었다. 그래서 재귀적으로 해당 문제를 풀기 위해 근접한 입력값들에 대해 어떤 규칙이 있는지 생각해 봤으며, 그 결과 다음과 같은 결론을 내릴 수 있었다.
- N을 출력하기 위해선 N//3의 출력 결과가 필요하다.
- N을 출력할 때는 N/3의 출력을 3번씩 3줄에 걸쳐 출력하면 된다. 이때 2줄의 2번째 출력은 공백이어야 한다.
위 사실을 알면 해당 문제를 어렵지 않게 풀 수 있다. (규칙은 어느 정도 잘 알아냈지만, 각 출력을 어떤 형태로 저장할지에 대한 고민이 조금 많긴 했다…)
📂 Code 1️⃣
재귀
함수를 작성할 때 중요한 점은 예외 처리를 해야 한다는 것이다.
여기선 n이 1일 때가 최초 입력이며 그때의 결과는 ‘*‘이므로 해당 문자를 반환하게 했다.
입력 n에 대해 별을 찍기 위해서는 n//3의 출력이 필요하므로 재귀 함수를 이용해 반환값을 저장하도록 했다.
입력이 n일 때 출력은 n줄 출력되므로 for문을 n번 돌며 위에 작성한 규칙에 따라 배열(result)에 문자열을 저장해 주었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def draw_star(n): # 배열(ans)에 ***를 저장
if n == 1:
return '*'
star = draw_star(n//3)
result = []
for i in range(n):
if (i // (n//3)) == 1:
result.append(star[i%(n//3)] + ' ' * (n//3) + star[i%(n//3)])
continue
result.append(star[i%(n//3)] * 3)
return result
ans = draw_star(int(input()))
for a in ans:
print(a)
📂 Code 2️⃣
위와 같이 코드를 작성하면서, 규칙에 따라 수식들을 작성하는 게 머리가 아팠다. 더 쉬운 방법이 있을 거 같아 구글링 해 본 결과 다음과 같이 더욱 간단하게 풀어냈다.
Code 1️⃣에서는 for문 하나에 걸쳐 모든 값을 저장하려고 했는데 그럴 필요가 없었다는 걸 깨달았다. 그렇게 풀이하려고 하니까 예외 처리 및 인덱스 접근을 하기 위해 수식 처리하는 것이 어려워졌다고 생각한다.
아래와 같이 이전 입력(n //3)에 대한 for문을 각각 3번 돌리면 출력이 더
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def draw_star(n):
if n == 1:
return '*'
stars = draw_star(n//3) # 이전 단계의 별의 패턴을 저장(재귀)
result = []
for s in stars:
result.append(s * 3)
for s in stars:
result.append(s + ' ' * (n//3) + s)
for s in stars:
result.append(s * 3)
return result
ans = draw_star(int(input()))
for a in ans:
print(a)