코딩 테스트/백준

[Python] 백준 2447 별찍기 - 10

위시리 2024. 9. 21. 01:46


문제 분석

  • n은 3의 제곱
  • 크기 n의 패턴 == nxn의 정사각형 패턴
  • 크기 9의 패턴 : 
  • 공백으로 채워진 가운데의 3x3 정사각형을
  • 크기 3의 패턴으로 둘러싼 형태

 

코드 설계

  • n 만큼의 * 패턴 생성
  • 전체 * 패턴을 3x3 배열로 쪼갠 뒤,
  • [1][1] 부분만 공백으로 변환하여 다시 합치기 (재귀)
  • 크기 3의 패턴 : 
import sys
input = sys.stdin.readline

# n = int(input())
n = 3

star = [['*'] * n for _ in range(n)]

def make_blank(star) :
    for i in range(n) :
        for j in range(n) :
            if i==1 and j==1 :
                star[i][j] = ' '

make_blank(star)

for i in range(len(star)):
    for j in range(len(star[0])):
        print(star[i][j], end=' ')
    print()

위 코드는 먼저 nxn만큼의 별을 찍고 재귀로 공백을 만들어가는 식으로 코드를 작성해본거다..

 

정답 코드

실패..

 

**

import sys
sys.setrecursionlimit(10 ** 6)

파이썬으로 재귀 문제를 풀면, 특히 dfs, bfs를 풀 때, 정답 제출을 하면 런타임 에러를 접하게 되는 경우가 있다. 런타임 에러가 발생하는 이유는 파이썬의 재귀 최대 깊이의 기본 설정이 1,000회이기 때문이다. 따라서 위와 같이 코드를 작성해주면 재귀의 최대 깊이가 10**6 (10^6)으로 바뀐다.

 

정답코드 1

참고 :

https://cotak.tistory.com/38

https://velog.io/@miiingirok/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B0%B1%EC%A4%80-2447.-%EB%B3%84-%EC%B0%8D%EA%B8%B0Python

import sys
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline

def make_pattern(len) :
    if len == 1 :
        return ['*']

    stars = make_pattern(len//3)
    l = []

    for s in stars:
        l.append(s*3)
    for s in stars:
        l.append(s + ' ' * (len//3) + s)
    for s in stars :
        l.append(s*3)
    return l

n = int(input())
print('\n'.join(make_pattern(n)))
  • 3번 출력을 할건데
  • 1번째 줄은 이전 패턴 그대로 다 가져다 붙이고
  • 2번째 줄은 패턴 + 공백 + 패턴
  • 3번째 줄은 첫번째 처럼
  • 이거를 재귀

 

정답코드 2

by chatGPT

import sys
input = sys.stdin.readline

def make_pattern(n):
    if n == 1:
        return ['*']

    # N//3 크기의 패턴을 재귀적으로 만듦
    smaller_pattern = make_pattern(n // 3)
    pattern = []

    for i in range(n):
        if (i // (n // 3)) % 3 == 1:  # 중앙 열
            # 중앙 부분 공백 추가
            pattern.append(smaller_pattern[i % (n // 3)] + ' ' * (n // 3) + smaller_pattern[i % (n // 3)])
        else:
            # 위아래 별 패턴을 세 번 반복
            pattern.append(smaller_pattern[i % (n // 3)] * 3)

    return pattern

# 입력 받기
n = int(input().strip())

# 패턴 생성
result = make_pattern(n)

# 결과 출력
for line in result:
    print(line)

 

  • 기본 패턴 정의:
    • N = 1일 때는 기본적으로 '*' 하나를 반환합니다.
  • 재귀적 패턴 생성:
    • make_pattern(n // 3)을 통해 더 작은 크기의 패턴을 먼저 생성합니다. 그 패턴을 이용해 가운데 부분을 공백으로 처리한 새로운 패턴을 만듭니다.
  • 중앙 공백 처리:
    • N×NN \times N 패턴에서 중앙의 (N/3)×(N/3)(N/3) \times (N/3) 부분을 공백으로 두고, 그 외곽 부분에 재귀적으로 생성된 작은 패턴을 배치합니다.
  • 출력:
    • 최종적으로 패턴을 한 줄씩 출력합니다.

 

다음에 한 번 더 해보자..