

x일 때, 속도를 줄여 x-1칸 / 속도를 유지해 x칸 / 속도를 늘려 x + 1칸 점프를 할 수 있습니다. 각각 경우가 간선으로 연결되어 있다고 생각하면 됩니다.
from collections import deque
import sys
input = sys.stdin.readline
# 돌의 수 (N), 방문할 수 없는 돌의 수 (M)
N, M = map(int, input().split())
# 이미 확인한 노드 - (돌번호, 점프속도)를 저장할 집합
checked = set()
# 방문할 수 없는 돌 번호를 저장할 집합
banned = set()
for _ in range(M):
banned.add(int(input()))
deque를 사용합니다.돌번호, 점프속도) 형태로 checked 집합에 저장해, 중복 방문을 방지합니다.banned 집합에 저장합니다.# (돌 번호, 점프속도, 점프 횟수)
queue = deque([(1, 0, 0)])
checked.add((1, 0))
queue에는 각 노드를 (돌 번호, 점프속도) 형태로 저장합니다.점프 횟수 (즉 거치는 간선 수)도 저장합니다.(1, 0, 0)을 푸시해줍니다.(1, 0)을 checked 집합에 더해줍니다.🤔왜 맨 처음에 점프 속도는 0인가요?
x일 때 감속해 x-1칸 점프하거나, 속도를 유지해 x칸 점프하거나, 가속해 x+1칸 점프할 수 있다고 합니다.x가 0일 때 -1칸, 0칸 점프는 불가능하므로, 첫 점프는 1칸만 가능합니다. 0으로 두어, 첫 점프가 무조건 1칸이 되게 합니다.def bfs():
while queue:
# 노드 맨 앞의 (돌 번호, 점프속도, 점프 횟수) 꺼내기
i, jump, dist = queue.popleft()
# 목적지에 도착한 경우, 점프 횟수 반환
if i == N:
return dist
# 속도-1 / 속도유지 / 속도+1 하는 경우 탐색
for offset in [-1, 0, 1]:
new_jump = jump + offset # 새로운 점프 속도 (다음에 점프할 칸 수)
if new_jump < 1: # 적어도 1칸 이상을 점프해야 함
continue
j = i + new_jump # 점프 이후 도착하는 돌번호
# 도착한 돌 번호가 N 이하인가?
# 올라갈 수 없는 돌이 아닌가?
# 이미 방문한 (돌 번호, 점프속도) 조합이 아닌가?
if j <= N and j not in banned and (j, new_jump) not in checked:
# 그러면 queue / checked에, 점프 수를 1 더해서 삽입
queue.append((j, new_jump, dist + 1))
checked.add((j, new_jump))
# 목적지에 도달하지 못할 때
return -1
(i: 돌 번호, jump: 점프 속도, dist: 점프 수)를 큐에서 꺼내 현재 상태를 확인하고, (노드 꺼내기)if new_jump < 1)는 무시합니다.banned에 포함된 올라갈 수 없는 돌은 아닌지 확인합니다.checked 집합에서 확인합니다.queue에 삽입하고 checked에 더해 줍니다. (방문 처리)# (돌 번호, 점프속도, 점프 수)
queue = deque([(1, 0, 0)])
checked.add((1, 0))
def bfs():
while queue:
# 노드 맨 앞의 (돌 번호, 점프속도, 점프 수) 꺼내기
i, jump, dist = queue.popleft()
# 목적지에 도착한 경우, 점프 수 반환
if i == N:
return dist
# 속도-1 / 속도유지 / 속도+1 하는 경우
for offset in [-1, 0, 1]:
new_jump = jump + offset # 새로운 점프 속도 (다음에 점프할 칸 수)
if new_jump < 1: # 적어도 1칸 이상을 점프해야 함
continue
j = i + new_jump # 점프 이후 도착하는 돌
# 도착한 돌 번호가 N 이하인가?
# 올라갈 수 없는 돌이 아닌가?
# 이미 방문한 (돌 번호, 점프속도) 조합이 아닌가?
if j <= N and j not in banned and (j, new_jump) not in checked:
# 그러면 queue / checked에, 점프 수를 1 더해서 삽입
queue.append((j, new_jump, dist + 1))
checked.add((j, new_jump))
return -1