https://www.acmicpc.net/problem/2661
🗒️파이썬 코드 풀이
N = int(input())
def check(lst):
for i in range(1,len(lst)//2+1): # 몇 개씩 확인 할 것인지
for j in range(len(lst)-i):
if lst[j:j+i] == lst[j+i:j+i+i]:
return False
return True
mn = 1e100
def dfs(n,lst):
# return -1로 상위 호출에서 다른 경로 탐색 제어
if not(check(lst)):
return -1
global mn
if n == N:
lst = list(map(str,lst))
mn = min(int("".join(lst)),mn)
return 0
for i in range(1,4):
lst.append(i)
if dfs(n+1,lst) == 0:
return 0
lst.pop()
dfs(0,[])
print(mn)
1. dfs에서 백트래킹 응용 문제로, 다소 복잡한 조건들이 있다.
2. 먼저 수열들이 "나쁜 수열"인지 "좋은 수열"인지를 파악해야한다.
이를 위한 check 함수를 만들어 준다.
for i in range(len(lst)-1):
print(lst[i:i+2],lst[i+2:i+2+2])
처음부터 바로 check 함수를 구현하기는 어렵기 때문에,
먼저 간단한 for문으로 테스트를 해본다.
(해당 for문은 2개씩 비교를 할 때의 예시이다.)
3. N의 범위가 80까지이므로, 가지치기를 잘 해줘야 한다.
CASE 1) 재귀함수를 실행할때 check 함수의 return이 False인 경우, 해당 재귀함수의 return을 -1로 하여 더 이상 상위 호출 탐색을 하지 않는다.
CASE 2) 가장 최소값을 찾는 것이기 때문에, 모든 조건을 만족하는 lst를 다 구할 필요가 없다. 재귀함수 특성상 가장 빨리 조건에 만족하는 수가 가장 작은 값이 된다.
(재귀함수 for문의 return 0으로 연쇄적으로 재귀함수들이 종료된다. )
이 두가지의 가지치기로 시간 초과를 막을 수 있다.
📌 문제 코멘트
check 함수 부분 구현이 좀 어려웠다.
먼저 경우의 수를 쪼개주고 하나 하나 구현해보자.
위의 문제 같은 경우, 이렇게 두가지 경우로 나눌 수 있다.
- 1개가 같은경우 / 2개가 같은 경우 / 3개가 같은경우 ...
- [~:1] ~[1:~]...
그리고 이 경우들을 한번에 작성하지말고,
간단한 for문 예시로 작성하면 좀 더 수월하게 가능하다.
또 어려웠던거는 단순 재귀함수가 아니라, 가지치기들 조건들이였다.
특히, return -1을 쓰는 것은 이번이 처음이었다.
그리고 재귀함수 for 문에 return 0을 활용한것도 처음이다.
확실히 골드 문제는 조건들이 많은거 같다.
📚문제
숫자 1, 2, 3으로만 이루어지는 수열이 있다. 임의의 길이의 인접한 두 개의 부분 수열이 동일한 것이 있으면, 그 수열을 나쁜 수열이라고 부른다. 그렇지 않은 수열은 좋은 수열이다.
다음은 나쁜 수열의 예이다.
- 33
- 32121323
- 123123213
다음은 좋은 수열의 예이다.
- 2
- 32
- 32123
- 1232123
길이가 N인 좋은 수열들을 N자리의 정수로 보아 그중 가장 작은 수를 나타내는 수열을 구하는 프로그램을 작성하라. 예를 들면, 1213121과 2123212는 모두 좋은 수열이지만 그 중에서 작은 수를 나타내는 수열은 1213121이다.
입력
입력은 숫자 N하나로 이루어진다. N은 1 이상 80 이하이다.
출력
첫 번째 줄에 1, 2, 3으로만 이루어져 있는 길이가 N인 좋은 수열들 중에서 가장 작은 수를 나타내는 수열만 출력한다. 수열을 이루는 1, 2, 3들 사이에는 빈칸을 두지 않는다.
예제 입력 1 복사
7
예제 출력 1 복사
1213121
'알고리즘 > 알고리즘_백준' 카테고리의 다른 글
[Python][백준] 1259. 팰린드롬수 / 구현,문자열 (B1) (0) | 2024.08.11 |
---|---|
[Python][백준] 1987. 알파벳 / 백트래킹,DFS (G4) (0) | 2024.08.11 |
[Python][백준] 6603. 로또 / 백트래킹,재귀,조합 (S2) (0) | 2024.08.09 |
[Python][백준] 15650. N과 M (2) / 백트래킹(S2) (0) | 2024.07.27 |
[Python][백준] 1780. 종이의 개수 / 분할정복,재귀 (S2) (0) | 2024.07.27 |