57 lines
2.1 KiB
Python
57 lines
2.1 KiB
Python
# 숨바꼭질 3
|
|
|
|
import sys
|
|
from collections import deque
|
|
|
|
input = sys.stdin.readline
|
|
|
|
MAX_LINE = 100000
|
|
|
|
def solution():
|
|
n, k = map(int, input().rstrip().split())
|
|
|
|
move = [1, -1]
|
|
visited = [float('inf')] * (MAX_LINE+1)
|
|
dq = deque([n])
|
|
visited[n] = 0
|
|
|
|
while dq:
|
|
now = dq.popleft()
|
|
|
|
if now == k:
|
|
break
|
|
|
|
teleport = now*2
|
|
while 0 <= teleport <= MAX_LINE and visited[teleport] > visited[now]:
|
|
dq.append(teleport)
|
|
visited[teleport] = visited[now]
|
|
teleport = teleport*2
|
|
|
|
for m in move:
|
|
moved = now+m
|
|
if 0 <= moved <= MAX_LINE and visited[moved] > visited[now]+1:
|
|
dq.append(moved)
|
|
visited[moved] = visited[now]+1
|
|
|
|
print(visited[k])
|
|
|
|
return
|
|
|
|
|
|
solution()
|
|
|
|
"""
|
|
걸린 시간: 39분
|
|
|
|
시간 복잡도: 한 노드를 pop했을 때 많아도 log(100000)정도이기 때문에 n=100000일때 O(nlogn)정도이다.
|
|
|
|
해설: 뱀과 사다리(16928)랑 비슷한 문제인 것 같다. 현재 위치에서 순간이동하는 곳은 같은 시간으로 넣어야 하고, 그 곳을 visited를
|
|
만드는 방식으로 진행하는 것이었다. 하지만 이 문제는 순간이동 위치가 1:1 대응이 아니고, 뒤로 순간이동 하는 것은 없다는 점에서 차이가 있다.
|
|
하지만 일단 중요한 건 bfs 레벨에서 순간이동에 대응되는 위치들이 다 같은 레벨이기 때문에 얘네를 큐에 순서대로 잘 넣는 것이다.
|
|
그렇게 했는데 99퍼센트에서 틀렸다고 나왔다.
|
|
생각해보니까 앞뒤로 이동해서 이미 방문해버린 것을 같은 턴에 순간이동으로 올 수 있었다면 더 나은 방법으로 올 수 있음.
|
|
예를 들어 4 6의 경우 4 8 16 .. 5 3 일때 5에서 6을 +1로 방문했는데, 사실 3에서 6으로 순간이동하면 +1 없이 갈 수 있다.
|
|
결국에는 또 같은 레벨의 구분을 제대로 하지 못했다.
|
|
일단 대안으로는 레벨 조정이 있겠지만 그냥 방문 기준으로 노드를 넣지 말고, 다 계산해봐서 지금 값보다 더 좋은 방향이 있다면 큐에 다시 추가하도록
|
|
조정하였다.
|
|
""" |