건물에 F층이 있고, 현재 S층에서 G층으로 이동하려고 한다.
엘리베이터 버튼은 두 가지:
U층 이동D층 이동목표는 최소 버튼 횟수로 G층에 도달하는 것이다.
도달할 수 없다면 "use the stairs"를 출력한다.
1. BFS로 접근해야 하는 이유
이 문제는 버튼을 한 번 누를 때마다 이동 횟수가 항상 1이다.
즉, 모든 이동 비용이 동일하므로 BFS로 최단 횟수를 구할 수 있다.
2. BFS 핵심 개념
BFS는 이동 횟수 기준으로 다음과 같이 탐색한다.
이 순서로 탐색하기 때문에
처음 방문한 순간이 곧 최소 이동 횟수가 된다.
1. 이미 방문한 층도 다시 갱신하려고 했던 접근
처음에는 아래처럼 생각했다.
“이미 방문한 층이라도, 더 적은 횟수로 도달할 수 있지 않을까? 더 짧으면 갱신해야지”
그래서 다음과 같이 코드를 작성했다.
if apt[moved] == 0:
apt[moved] = apt[current] + 1
else:
apt[moved] = min(apt[current] + 1, apt[moved])
즉, 더 작은 값이 나오면 갱신하려는 방식이었다.
하지만 이 접근은 BFS에서는 필요 없는 로직이었다.
이 문제는 버튼 한 번 누를 때마다 비용이 전부 같다. 위로 가기 1번, 아래로 가기 1번.
즉 모든 간선의 가중치가 1인 그래프이다.
반대로 이런 경우는 다르다.만약 가중치가 다른 상황이면(예를들어 엘리베이터 위로 가면 10초, 아래로 가면 1초)
BFS 안됨. 나중에 더 빠른 경로가 생길 수 있다. (이게 다익스트라)
2. 방문 체크 없이 큐에 계속 추가한 문제
또 하나의 문제는 다음 코드였다.
queue.append(moved)
방문 여부를 확인하지 않고 무조건 큐에 넣었기 때문에:
3. dist 배열 초기값 문제
처음에는 0으로 초기화했는데:
00이 둘이 구분되지 않아 로직이 꼬였다.
그래서 -1로 초기화하여 명확히 구분하도록 수정했다.
1. dist 배열을 -1로 초기화 (미방문 표시)
2. 시작점 S를 큐에 넣고 dist[S] = 0
3. BFS 수행
현재 층에서
범위 안이고 아직 방문하지 않은 경우만 큐에 추가
4. 목표 G에 도달하면 종료
5. dist[G]가 -1이면 도달 불가
from collections import deque
F, S, G, U, D = map(int, input().split())
dist = [-1] * (F + 1)
dist[S] = 0
queue = deque([S])
while queue:
current = queue.popleft()
if current == G:
break
for moved in (current + U, current - D):
if 1 <= moved <= F and dist[moved] == -1:
dist[moved] = dist[current] + 1
queue.append(moved)
if dist[G] == -1:
print("use the stairs")
else:
print(dist[G])
1. BFS에서는 재방문 갱신이 필요 없다
min() 갱신 로직 불필요2. 방문 체크는 큐에 넣기 전에 한다
3. 거리 배열은 -1로 초기화하는 것이 안전하다
4. 판단 기준 정리