수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
둘째 줄에 어떻게 이동해야 하는지 공백으로 구분해 출력한다.
풀이
단순한 BFS 문제이지만 이 문제가 골드 4인 이유는 바로 경로를 출력해야하기 때문.
앞으로 경로를 출력하는 문제가 굉장히 많이 나올 것이지만 이 문제는 그것의 기초의 기초의 기초의 왕기초.. 연습문제라고 본다
처음에는 다들 이렇게 짤 것이다(나도 이렇게 짰다)
from collections import deque
N, K = map(int, input().split())
visited = [False] * 100001
Q = deque()
Q.append((N, 0, [N]))
visited[N] = True
while Q:
node, time, path = Q.popleft()
if node == K:
print(time)
print(*path)
break
if 2*node <= 100000 and not visited[2*node]:
Q.append((2*node, time + 1, path + [2*node]))
visited[2*node] = True
if node + 1 <= 100000 and not visited[node + 1]:
Q.append((node + 1, time + 1, path + [node + 1]))
visited[node + 1] = True
if node - 1 >= 0 and not visited[node - 1]:
Q.append((node - 1, time + 1, path + [node - 1]))
visited[node - 1] = True
이렇게 하면 결과는 시간초과, 그리고 메모리초과이다. 왜? 그 긴 리스트들을 전부 큐 안에 저장하니까.
여기에는 Skill이 하나 필요하다.
바로 어떤 노드를 방문했을 때 그 전 노드에는 어디 있었는지를 저장하는 리스트를 만들면, 경로를 역추적할 수 있다.
그리고 이 문제에서는 이 리스트를 visited를 응용해서 만들 수 있다!
처음에 visited는 전부 -1로 해주고, 어떤 노드에 도달하게 되면 visited의 해당 노드 인덱스의 값은 바로 전에 있었던 노드의 인덱스를 저장해주면 된다. 즉, visited가 -1이 아니면 방문한 것으로 처리되는 것이다.
그리고 마지막에 이 리스트를 역으로 추적해나가면 되는 단순한 방식이다.
from collections import deque
N, K = map(int, input().split())
visited = [-1] * 100001
Q = deque()
Q.append((N, 0))
visited[N] = N
ans = []
while Q:
node, time = Q.popleft()
if node == K:
print(time)
now = node
while now != visited[now]:
ans.append(now)
now = visited[now]
ans.append(N)
if 2*node <= 100000 and visited[2*node] == -1:
Q.append((2*node, time + 1))
visited[2*node] = node
if node + 1 <= 100000 and visited[node + 1] == -1:
Q.append((node + 1, time + 1))
visited[node + 1] = node
if node - 1 >= 0 and visited[node - 1] == -1:
Q.append((node - 1, time + 1))
visited[node - 1] = node
print(*ans[::-1])
'PS' 카테고리의 다른 글
[Python] 백준 1509 - 팰린드롬 분할 (0) | 2025.03.18 |
---|---|
[Python] 백준 1182 - 부분수열의 합 (0) | 2025.03.13 |
[Python] 백준 17425 - 약수의 합 (0) | 2025.03.10 |
[Python] 백준 17484 - 진우의 달 여행 (Small) (0) | 2025.03.09 |
PS를 '또' 다시 시작하게 된 계기 (0) | 2025.03.09 |