Skip to content

Conversation

@learntosurf
Copy link
Collaborator

@learntosurf learntosurf commented Apr 19, 2025

rebase을 잘못한 걸 수습한다고 PR을 따로 분리해서 올리면서 이전 커밋이 날라갔습니다.,,,
발제 문제 커밋이 그래서 이전 PR에 포함되었어요,,, 번거로우시겠지만 코멘트가 있으면 다른 곳에 남겨주시면 감사하겠습니다!!

🌱WIL

  • 이번 스터디 발제 문제를 풀면서 백트래킹 유형이 처음이라는 것을 알게 되었다. 발제 문제 풀이를 들으면서까지는 정확히 어떤 느낌인지 잘 와닿지는 않았는데 조건 있는 완전탐색이라고 보면 되는 건가 라는 느낌으로 이해했다. 종료조건을 꼭 정의하고, 선택하지 않은 경우의 수를 탐색하고, 선택을 계속 반영해주는 것이 특징인 것 같다. 다른 기본 문제들을 같이 풀어봐야겠다.
    def backtrack(상태):
        if 종료조건(상태):
            정답 처리
            return
    
        for 선택 in 가능한 선택들:
            if 유효하지 않은 선택:
                continue
    
            상태에 선택 추가
            backtrack(업데이트된 상태)
            선택 되돌리기 (상태 복구)
  • 매주 한 주제씩은 개념+기본문제+발제/과제 난이도 문제를 정리하면서 가고 싶은데 매번 작심N일이다(근데 이제 N이 3이하일때...). 다음주는 백트래킹이나 DP 문제 유형을 풀어보고싶다! 실버 문제들을 많이 풀어보고 힌트 없이 쓱쓱 풀어낼 수 있게 만들고 싶다. 일단 꾸준히 하기 🫠

🚀주간 목표 문제 수: 3개

푼 문제


백준 #1759. 암호 만들기: 백트래킹 / 골드5

🚩제출한 코드

import sys 
input = sys.stdin.readline
from itertools import combinations

L, C = map(int, input().split())
chars = input().split()
chars.sort() # 오름차순 정렬 

vowels = set('aeiou')
result = []

# 백트래킹: 해를 찾는 도중 해가 아니어서 막히면, 되돌아가서 다시 해를 찾아가는 기법
# 현재까지 만든 암호의 길이가 L이면 종료 조건 
# 모음/자음 개수를 체크해서 만족할 경우 출력 
# 그렇지 않으면 다음 알파벳을 선택해 재귀 호출 
def backtrack(path, start):
    # 1. 종료 조건: 길이가 L이면 조합 완성 
    if len(path) == L: 
        vowel_count = 0 
        consonant_count = 0 
        
        # 모음/자음 개수 세기 
        for ch in path: 
            if ch in vowels: 
                vowel_count += 1
            else: 
                consonant_count += 1 
        
        # 조건에 맞으면 출력 
        if vowel_count >= 1 and consonant_count >= 2: 
            print(''.join(path))
        return 
    
    # 2. 가능한 모든 문자에 대해 선택
    for i in range(start, C): # C == len(chars)
        # 선택 
        path.append(chars[i])
        # 재귀 호출(다음 문자 선택) - 조합이므로 i+1부터
        backtrack(path, i+1)
        # 선택 취소  
        path.pop()
        
# 탐색 시작 
backtrack([], 0)

백준 #6603. 로또: 백트래킹 / 실버2

🚩제출한 코드

import sys

def backtrack(S, path, start):
    if len(path) == 6:
        print(' '.join(map(str, path)))
        return
    for i in range(start, len(S)):
        path.append(S[i])
        backtrack(S, path, i + 1)
        path.pop()

lines = sys.stdin.read().splitlines()
first_case = True

for line in lines:
    if line == '0':
        break

    parts = list(map(int, line.strip().split()))
    S = parts[1:]

    if not first_case:
        print()
    first_case = False

    backtrack(S, [], 0)

백준 #15649. N과 M (1): 백트래킹 / 실버3

🚩제출한 코드

N, M = map(int, input().split())
visited = [False] * (N + 1)  # 1부터 N까지 사용 여부
result = []

def backtrack():
    if len(result) == M:
        print(' '.join(map(str, result)))
        return
    
    for i in range(1, N + 1):
        if not visited[i]:
            visited[i] = True
            result.append(i)
            backtrack()
            result.pop()         # 상태 복원
            visited[i] = False   # 방문 초기화

backtrack()

Copy link
Collaborator

@Mingguriguri Mingguriguri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

암호 만들기 문제

  • set('aeiou')로 해도 {'u', 'o', 'e', 'i', 'a'}으로 문자가 나뉘어 저장될 수 있다는 점을 새롭게 알게 되었습니다!

  • 백트래킹 유형이 처음이었군요! 앞 부분에 유형 정의 부분을 넣을 걸 그랬군용... 백트래킹은 해가 될 수 없는 경우를 미리 파악하여 탐색을 중단하고, 다른 경로를 탐색하는 기법이에요!
    DFS는 모든 경로를 탐색해서 불필요한 경로까지 다 탐색을 합니다. 하지만 백트래킹은 해를 찾는 도중에 지금의 경로가 해가 되지 않으면 그 경로로 더이상 가지 않고 되돌아갑니다. 이 부분이 종료 조건을 설정하는 이유이기도 해요!
    DFS완전탐색과 같이 모든 경우의 수를 탐색하는 과정에서 특정한 조건을 만족하는 경우만 보는 게 백트래킹입니다!
    도움이 되셨으면 좋겠습니다!

  • 저도 매주 작심 N일..... 그래도 4월 말까지 챌린지도 달성할 수 있도록 화이팅입니다!

Comment on lines +12 to +17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sys.stdin.read().splitlines()는 파이썬에서 표준 입력(stdin)으로부터 전체 내용을 읽고, 줄바꿈 문자를 기준으로 텍스트를 분리하여 리스트 형태로 반환합니다.

여러 줄 읽을때 항상 반복문안에 readline 함수써서 구현했는데 sys.stdin.read().splitlines()한번 쓰면 알아서 줄바꿈 기준으로 문자열 리스트를 만들어 주네요.
오늘 소소한 꿀팁 배워갑니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sys.stdin.read().splitlines() 으로 여러 줄의 입력을 리스트 변수로 한번에 받을 수 있는건 처음 알았네요.
저도 다음에 꼭 사용해보겠습니다.

@learntosurf learntosurf merged commit 387a593 into main Apr 27, 2025
@github-actions
Copy link

🔥2025-04 챌린지 진행 상황

👉 그래프

  • YoonYn9915: 1개 ❌
  • Mingguriguri: 2개 ❌
  • zaqquum: 4개 ❌

👉 DP

  • YoonYn9915: 2개 ❌
  • Mingguriguri: 6개 ✅
  • zaqquum: 4개 ❌

1 similar comment
@github-actions
Copy link

🔥2025-04 챌린지 진행 상황

👉 그래프

  • YoonYn9915: 1개 ❌
  • Mingguriguri: 2개 ❌
  • zaqquum: 4개 ❌

👉 DP

  • YoonYn9915: 2개 ❌
  • Mingguriguri: 6개 ✅
  • zaqquum: 4개 ❌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants