diff --git "a/_WeeklyChallenges/W19-[Graph-Backtracking]/Assignment_BOJ_6603_\353\241\234\353\230\220.py" "b/_WeeklyChallenges/W19-[Graph-Backtracking]/Assignment_BOJ_6603_\353\241\234\353\230\220.py" index 818569dd..80e17b13 100644 --- "a/_WeeklyChallenges/W19-[Graph-Backtracking]/Assignment_BOJ_6603_\353\241\234\353\230\220.py" +++ "b/_WeeklyChallenges/W19-[Graph-Backtracking]/Assignment_BOJ_6603_\353\241\234\353\230\220.py" @@ -4,4 +4,49 @@ 유형: Graph, Backtracking """ -# 토요일에 업로드 예정 \ No newline at end of file +""" +#6603. 로또 +백트래킹 풀이 +""" +import sys +input = sys.stdin.readline +def backtrack(lotto, current): + if len(lotto) == 6: # 종료조건 + print(' '.join(map(str, lotto))) + return + + for i in range(current, k): + lotto.append(S[i]) + backtrack(lotto, i+1) + lotto.pop() + + +while True: + testcase = input().strip() + if testcase == '0': + break + nums = list(map(int, testcase.split())) + k, S = nums[0], nums[1:] + + backtrack([], 0) + print() + + +""" +#6603. 로또 +조합 풀이 +""" +import sys +from itertools import combinations +input = sys.stdin.readline + +while True: + testcase = input().strip() + if testcase == '0': + break + nums = list(map(int, testcase.split())) + k, S = nums[0], nums[1:] + combs = list(combinations(S, 6)) + for comb in combs: + print(' '.join(map(str, comb))) + print() \ No newline at end of file diff --git "a/minjeong/Backtracking/2025-04-16-[\353\260\261\354\244\200]-#6603-\353\241\234\353\230\220(\353\260\261\355\212\270\353\236\230\355\202\271\355\222\200\354\235\264).py" "b/minjeong/Backtracking/2025-04-16-[\353\260\261\354\244\200]-#6603-\353\241\234\353\230\220(\353\260\261\355\212\270\353\236\230\355\202\271\355\222\200\354\235\264).py" new file mode 100644 index 00000000..604434df --- /dev/null +++ "b/minjeong/Backtracking/2025-04-16-[\353\260\261\354\244\200]-#6603-\353\241\234\353\230\220(\353\260\261\355\212\270\353\236\230\355\202\271\355\222\200\354\235\264).py" @@ -0,0 +1,28 @@ +import sys +input = sys.stdin.readline + +""" +#6603. 로또 +백트래킹 풀이 +""" + +def backtrack(lotto, current): + if len(lotto) == 6: # 종료조건 + print(' '.join(map(str, lotto))) + return + + for i in range(current, k): + lotto.append(S[i]) + backtrack(lotto, i+1) + lotto.pop() + + +while True: + testcase = input().strip() + if testcase == '0': + break + nums = list(map(int, testcase.split())) + k, S = nums[0], nums[1:] + + backtrack([], 0) + print() diff --git "a/minjeong/Combinatorics/2025-04-16-[\353\260\261\354\244\200]-#6603-\353\241\234\353\230\220(\354\241\260\355\225\251\355\222\200\354\235\264).py" "b/minjeong/Combinatorics/2025-04-16-[\353\260\261\354\244\200]-#6603-\353\241\234\353\230\220(\354\241\260\355\225\251\355\222\200\354\235\264).py" new file mode 100644 index 00000000..0c692324 --- /dev/null +++ "b/minjeong/Combinatorics/2025-04-16-[\353\260\261\354\244\200]-#6603-\353\241\234\353\230\220(\354\241\260\355\225\251\355\222\200\354\235\264).py" @@ -0,0 +1,19 @@ +import sys +from itertools import combinations +input = sys.stdin.readline + +""" +#6603. 로또 +조합 풀이 +""" + +while True: + testcase = input().strip() + if testcase == '0': + break + nums = list(map(int, testcase.split())) + k, S = nums[0], nums[1:] + combs = list(combinations(S, 6)) + for comb in combs: + print(' '.join(map(str, comb))) + print() \ No newline at end of file diff --git "a/minjeong/DynamicProgramming/2025-04-14-[\353\260\261\354\244\200]-#1759-\354\225\224\355\230\270\353\247\214\353\223\244\352\270\260.py" "b/minjeong/DynamicProgramming/2025-04-14-[\353\260\261\354\244\200]-#1759-\354\225\224\355\230\270\353\247\214\353\223\244\352\270\260.py" new file mode 100644 index 00000000..a6eb0927 --- /dev/null +++ "b/minjeong/DynamicProgramming/2025-04-14-[\353\260\261\354\244\200]-#1759-\354\225\224\355\230\270\353\247\214\353\223\244\352\270\260.py" @@ -0,0 +1,32 @@ +import sys +input = sys.stdin.readline + +L, C = map(int, input().split()) # L: 암호 길이, C: 문자 종류 +chars = sorted(input().split()) # 사전순 정렬 +vowels = {'a', 'e', 'i', 'o', 'u'} + + +def is_valid(word): + # 최소 한 개의 모음과 최소 두 개의 자음으로 구성되어있는지 확인 + vowel_cnt, consonant_cnt = 0, 0 # 모음 개수, 자음 개수 + for w in word: + if w in vowels: + vowel_cnt += 1 + else: + consonant_cnt += 1 + + return vowel_cnt >= 1 and consonant_cnt >= 2 + + +def backtrack(word, start): + if len(word) == L: # 종료 조건 + if is_valid(word): + print(''.join(word)) + return + + for i in range(start, C): + word.append(chars[i]) + backtrack(word, i+1) + word.pop() + +backtrack([], 0) diff --git "a/minjeong/DynamicProgramming/2025-04-17-[\353\260\261\354\244\200]-#9084-\353\217\231\354\240\204.py" "b/minjeong/DynamicProgramming/2025-04-17-[\353\260\261\354\244\200]-#9084-\353\217\231\354\240\204.py" new file mode 100644 index 00000000..0b688609 --- /dev/null +++ "b/minjeong/DynamicProgramming/2025-04-17-[\353\260\261\354\244\200]-#9084-\353\217\231\354\240\204.py" @@ -0,0 +1,17 @@ +import sys +input = sys.stdin.readline + +T = int(input()) +for _ in range(T): + N = int(input()) # 동전의 가지 수 + coins = list(map(int, input().split())) # N가지 동전의 각 금액 + M = int(input()) # 목표 금액 + + dp = [0] * (M+1) + dp[0] = 1 + + for coin in coins: + for i in range(coin, M + 1): + dp[i] += dp[i - coin] + + print(dp[M]) \ No newline at end of file diff --git "a/minjeong/DynamicProgramming/2025-04-18-[\353\260\261\354\244\200]-#1053-\355\214\260\353\246\260\353\223\234\353\241\254\352\263\265\354\236\245.py" "b/minjeong/DynamicProgramming/2025-04-18-[\353\260\261\354\244\200]-#1053-\355\214\260\353\246\260\353\223\234\353\241\254\352\263\265\354\236\245.py" new file mode 100644 index 00000000..b60e463f --- /dev/null +++ "b/minjeong/DynamicProgramming/2025-04-18-[\353\260\261\354\244\200]-#1053-\355\214\260\353\246\260\353\223\234\353\241\254\352\263\265\354\236\245.py" @@ -0,0 +1,52 @@ +import sys +input = sys.stdin.readline + + +def min_ops_to_pal(s): + """ + s: list of chars + return: 최소 편집 연산(삽입, 삭제, 교체만 허용)으로 s를 팰린드롬으로 만드는 비용 + """ + n = len(s) + # dp[i][j]: s[i..j]를 팰린드롬으로 만드는 최소 연산 횟수 + dp = [[0] * n for _ in range(n)] + # 길이 2부터 n까지 늘려가며 + for length in range(2, n + 1): + for i in range(n - length + 1): + j = i + length - 1 + if s[i] == s[j]: + dp[i][j] = dp[i + 1][j - 1] + else: + # 교체(대칭 맞추기), 삭제(왼쪽), 삭제(오른쪽) + dp[i][j] = min( + dp[i + 1][j - 1] + 1, + dp[i + 1][j] + 1, + dp[i][j - 1] + 1 + ) + for d in dp: + print(d) + + return dp[0][n - 1] if n > 0 else 0 + + +s = list(input().rstrip()) +n = len(s) + +# 1. 교환 없이 삽입/삭제/교체만 사용했을 때 +ans = min_ops_to_pal(s) +if ans <= 1: + print(ans) + exit() + +# 2. 서로 다른 문자끼리 한 번만 교환을 허용해봤을 때, 교환 비용 1을 더해보고 개선되는지 확인 +for i in range(n): + for j in range(i + 1, n): + if s[i] != s[j]: + # 문자가 같지 않은 경우, SWAP + s[i], s[j] = s[j], s[i] + swap_cost = min_ops_to_pal(s) + 1 # swap 비용 포함 + if swap_cost < ans: # swap한 경우가 더 작다면 ans에 업데이트 + ans = swap_cost + # 복구 + s[i], s[j] = s[j], s[i] +print(ans)