처음 문제를 보고 DP
가 아닐까 생각을 했다.
십의 자리
가 3
일 때를 생각해보면 올 수 있는 일의 자리
는 2
, 1
, 0
이 된다.
마찬가지로 백의 자리
가 3
일 때를 생각해보면 올 수 있는 십의 자리
는 2
, 1
, 0
이 된다.
여기서 일의 자리
는 생각안해도 된다. DP
를 사용했기 때문이다.
일의 자리
=> [[0]
, [1]
, [2]
, [3]
, [4]
, [5]
, [6]
, [7]
, [8]
, [9]
]
십의 자리
=> [[]
, [[1, 0]]
, [[2, 0], [2, 1]]
, [[3, 0], [3, 1], [3, 2]]
] ...
백의 자리
=> [[]
, []
, [[2, 1, 0]]
, [[3, 1, 0], [3, 2, 0], [3, 2, 1]]
] ...
점화식으로 나타내면 DP[자리 수][인덱스] => DP[자리수 - 1][0] + DP[자리수 - 1][1] ... DP[자리수][인덱스 - 1] 라고 생각했다.
def solution():
n = int(sys.stdin.readline())
dp = []
cnt = 0
flg = False
while True:
tmp = []
for i in range(10):
if not dp:
tmp.append([[i]])
if cnt == n:
flg = True
print(i)
break
cnt += 1
else:
prev = dp[-1]
t = []
for j in range(i):
idx_arr = prev[j]
for k in idx_arr:
t.append([i] + k)
if cnt == n:
flg = True
print(''.join(map(str, ([i] + k))))
cnt += 1
tmp.append(t)
dp.append(tmp)
if flg or cnt == 1023:
break
if not flg:
print(-1)
solution()
끝나는 시점은 cnt
가 1023
일 때이므로 종료조건을 추가해주었다.
하지만 상당히 복잡하다는 점이 문제이다.
문제 힌트에서 브루트 포스
, 백트래킹
이 있었다.
힌트를 보고 무릎을 탁 쳤다.
def solution():
n = int(sys.stdin.readline())
tmp = []
def backtracking(num):
if len(num) == pos:
tmp.append(int(num))
return
last = int(num[-1])
for i in range(10):
if last > i:
backtracking(num + str(i))
else:
break
for pos in range(1, 11):
for i in range(10):
backtracking(str(i))
if n >= len(tmp):
print(-1)
else:
print(tmp[n])
solution()
백트래킹으로 이전 숫자last
보다 더 작은 숫자i
를 계속 추가하고 숫자num
이 자릿수pos
와 같다면 배열tmp
에 추가해준다.
또한 순서도 보장되므로 인덱스에 맞게 출력해주면 된다.