알고리즘/백준

0306. [BOJ#4779] 칸토어 집합

Jinoo.keem 2024. 3. 6. 23:45
728x90

https://www.acmicpc.net/problem/4779

 

4779번: 칸토어 집합

칸토어 집합은 0과 1사이의 실수로 이루어진 집합으로, 구간 [0, 1]에서 시작해서 각 구간을 3등분하여 가운데 구간을 반복적으로 제외하는 방식으로 만든다. 전체 집합이 유한이라고 가정하고,

www.acmicpc.net

1 초 128 MB 13426 6145 5026 45.052%

문제

칸토어 집합은 0과 1사이의 실수로 이루어진 집합으로, 구간 [0, 1]에서 시작해서 각 구간을 3등분하여 가운데 구간을 반복적으로 제외하는 방식으로 만든다.

전체 집합이 유한이라고 가정하고, 다음과 같은 과정을 통해서 칸토어 집합의 근사를 만들어보자.

1. -가 3N개 있는 문자열에서 시작한다.

2. 문자열을 3등분 한 뒤, 가운데 문자열을 공백으로 바꾼다. 이렇게 하면, 선(문자열) 2개가 남는다.

3. 이제 각 선(문자열)을 3등분 하고, 가운데 문자열을 공백으로 바꾼다. 이 과정은 모든 선의 길이가 1일때 까지 계속 한다.

예를 들어, N=3인 경우, 길이가 27인 문자열로 시작한다.

---------------------------

여기서 가운데 문자열을 공백으로 바꾼다.

---------         ---------

남은 두 선의 가운데 문자열을 공백으로 바꾼다.

---   ---         ---   ---

한번 더

- -   - -         - -   - -

모든 선의 길이가 1이면 멈춘다. N이 주어졌을 때, 마지막 과정이 끝난 후 결과를 출력하는 프로그램을 작성하시오.

입력

입력을 여러 줄로 이루어져 있다. 각 줄에 N이 주어진다. 파일의 끝에서 입력을 멈춘다. N은 0보다 크거나 같고, 12보다 작거나 같은 정수이다.

출력

입력으로 주어진 N에 대해서, 해당하는 칸토어 집합의 근사를 출력한다.


제출 코드

# 3**3 이면 길이가 27이고 인덱스가 0~26인 문자열
# 가운데 문자열을 공백
# 남은 두선의 가운데 문자열을 공백

# 시작점 + 끝점//3 = 첫번째 구간끝점 
# -------공백문자 넣을 공간-------
# 시작점 + (끝점//3)*2 = 두번째 구간 시작점

# 반복 > 문자열의 길이가 1이 되면 멈춤

def recur(start, end):
    if end == 1:
        return
    
    for i in range(start + end//3, start + (end//3)*2): # 중간지점
        st[i] = ' '
    recur(start, end//3) # 시작점부터 1/3 지점까지
    recur(start + (end//3)*2, end//3) # 2/3 지점부터 끝까지

while True:
    try:
        N = int(input())
        st = ['-'] * (3**N)
        recur(0, 3**N)
        print(*st, sep='')
    except EOFError: 
        break

처음에 포문으로만 풀어보려다가 안되서 재귀로 푼 문제. 근데 재귀도 범위설정을 잘 못해서 결국 검색의 힘을 빌렸다..

재귀를 잘 풀려면 규칙을 잘 찾고 기저문을 잘 설정해야되는데 아직 많이 부족함을 느낀 문제.

except문의 에러들도 다시 공부해야겠다.

'알고리즘 > 백준' 카테고리의 다른 글

0308. [BOJ#14501] 퇴사  (0) 2024.03.09
0307. [BOJ#4673] 셀프 넘버  (1) 2024.03.07
0305. [BOJ#1244] 스위치 켜고 끄기  (0) 2024.03.05
0303. [BOJ#2578] 빙고  (0) 2024.03.03
0302. [BOJ#2628] 종이 자르기  (0) 2024.03.02