Programming/백준
[골드 4] 백준 2661 - 좋은수열 (파이썬)
pental
2025. 7. 30. 23:12
분류 : 백트래킹
링크 : https://www.acmicpc.net/problem/2661
풀이
이 문제는 숫자 1, 2, 3 으로만 이루어지는 수열이 있으며, 임의의 길이의 인접한 두 개의 부분 수열이 동일한 것이 있으면, 그 수열은 나쁜 수열이라고 한다.
좋은 수열은 인접한 두 개의 부분 수열이 동일하면 안된다. 즉 1212는 마지막 두자리 12가 반복되므로 나쁜 수열이다.
길이 N의 좋은 수열 중 사전순으로 가장 앞서는 수열을 찾아야한다.
def is_good(seq) :
length = len(seq)
for i in range(1, length // 2 + 1) :
if seq[-i:] == seq[-2 * i : -i] :
return False
return True
이 함수는 현재 수열이 좋은 수열인지 판단한다.
i는 검사할 패턴의 길이, 최대 length // 2 까지만 확인하면 충분하다.
예를 들어서 123123에서는 뒤에서부터 길이 3까지의 패턴 123을 비교한다.
seq[-i:]는 마지막 i개의 문자, seq[-2*i:-i]는 그 앞 i개의 문자를 나타내며, 두부분이 같다면 반복되는 패턴이므로 나쁜수열이다.
반복이 없다면 좋은 수열을 나타낸다.
def dfs(seq) :
global found
if found : return
if len(seq) == N :
print(seq)
found = True
return
for digit in '123' :
new_seq = seq + digit
if is_good(new_seq) :
dfs(new_seq)
현재 수열 seq를 기반으로 깊이우선탐색을 진행한다.
수열의 길이가 N이 되면 출력하고 종료하고, 숫자 1, 2, 3을 하나씩 붙여가면서 수열을 확장한다.
붙였을때 좋은 수열인지 검사 후 통과하면 재귀를 호출한다.
좀 어려운 문제인데 이게 어떻게 정답률이 50%..
코드
# 백준 2661 - 좋은수열
# 분류 : 백트래킹
N = int(input())
found = False
def is_good(seq) :
length = len(seq)
for i in range(1, length // 2 + 1) :
if seq[-i:] == seq[-2 * i : -i] :
return False
return True
def dfs(seq) :
global found
if found : return
if len(seq) == N :
print(seq)
found = True
return
for digit in '123' :
new_seq = seq + digit
if is_good(new_seq) :
dfs(new_seq)
dfs("")