문제
kriii는 1부터 N까지의 수로 이루어진 순열을 파일로 저장해 놓았다. 모든 수는 10진수로 이루어져 있고, 모두 공백으로 분리되어 있다.
그런데 sujin이 그 파일의 모든 공백을 지워버렸다!
kriii가 순열을 복구하도록 도와주자.
입력
첫 줄에 공백이 사라진 kriii의 수열이 주어진다.
kriii의 순열은 최소 1개 최대 50개의 수로 이루어져 있다.
출력
복구된 수열을 출력한다. 공백을 잊으면 안 된다.
복구한 수열의 경우가 여러 가지 일 경우, 그 중 하나를 출력한다.
★ 시작하기 전에
백트래킹이자, dfs 문제이다.
처음에는 막연했다.. 이거 모든 경우 다 하라는 건가? >>>>>>>>>>>>맞다.. ㅎㅎ;
최대 50이니까 2자리까지가 최대이므로 1칸, 2칸씩 나누면서 조건을 만족하는지 확인해야 한다.
결국! 조건을 적절히 걸어서 재귀적으로 풀어야 한다.
import sys
input = sys.stdin.readline
data = input().strip()
length = len(data) # 길이를 통해 N의 값을 구해야한다.
k = length
n = 1
while k // ( 10**n - 10**(n-1) ):
k -= ( 10**n - 10**(n-1) )
n += 1
N = 10**(n-1) + (k)//n - 1 # 최댓값 먼저 구하자.
check = [0 for _ in range(N)] # 숫자를 사용했는지 안했는지 확인하는 리스트
result = []
def find(idx, word=[]):
global result
if len(word) > N: # 길이보다 길어지면 종료!
return
if len(word) == N: # 길이만큼 찻으면 결과값을 넣자
result.append(' '.join(word))
return
# 한단계씩 넣는 조건
if (idx <= length-1) and int(data[idx])>0 :
a = data[idx]
if int(a) <= N and check[int(a)-1] == 0:
check[int(a)-1] = 1
word.append(a)
find(idx+1, word)
word.pop()
check[int(a)-1] = 0
# 두단계씩 넣는 조건(2자리씩 넣는다)
if idx+1 <= length-1:
a = data[idx:idx+2]
if int(a) <= N and check[int(a)-1] ==0 :
check[int(a)-1] = 1
word.append(a)
find(idx+2, word)
word.pop()
check[int(a)-1] = 0
return
find(0)
print(result[0])
나의 풀이는 계속 틀렸었다..
이유는 0도 따로 넣어서 계산했기 때문이었다. 그래서 조건으로 0 이상을 넣어서 풀었더니.. 간신히 통과
너무 난잡해 보이는 풀이이고 다음은 깔끔하고 습득하고 싶은 풀이를 추가로 적어봤다. 같이 스터디하는 고수의 풀이!
접근법은 같지만 사용했는지 안했는지와 미리 리스트를 만든다면 더 깔끔하게 풀리는 풀이이다.
import sys
input = sys.stdin.readline
def makeIt(index, c):
global finish, ans
if finish: return
if index==len(num):
if c==maxN:
finish = True
ans = " ".join(map(str, tmp))
return
# 한자리 숫자나 두자리 숫자로 탐색
# 깔끔하게 사용했는지 안했는지만 확인하고 append가 아닌 미리 만든 리스트를 바꾸는 방식!
num1 = int(num[index])
if not used[num1]: # 만약 한자리 숫자가 사용되지 않았다면 재귀 ㄱㄱ
used[num1] = True
tmp[c] = num1
makeIt(index+1, c+1)
used[num1] = False
if index<len(num)-1: # 만약 두자리 숫자가 사용되지 않았다면 재귀 ㄱㄱ
num2 = int(num[index:index+2])
if num2 < maxN+1 and not used[num2]:
used[num2] = True
tmp[c] = num2
makeIt(index+2, c+1)
used[num2] = False
num = input().strip()
if len(num)<10:
maxN = len(num)
else:
maxN = 9+(len(num)-9)//2 # 최댓값을 똑같이 구해준다.
used = [0 for _ in range(maxN+1)]
tmp = [0 for _ in range(maxN)]
finish = False
makeIt(0,0)
print(ans)
'백준_알고리즘' 카테고리의 다른 글
[백준] 16234. BFS_인구이동 - Python (0) | 2021.03.15 |
---|---|
[백준] 3055. BFS_탈출 - Python (0) | 2021.03.15 |
[백준] 14888. 백트래킹_연산자끼워넣기 - Python (0) | 2021.03.09 |
[백준] 2210. DFS_숫자판점프 - Python (0) | 2021.03.02 |
[백준] 1325. DFS_효율적인해킹 - Python (0) | 2021.03.02 |