이번 문제는 13549번 숨바꼭질 3이다

문제 요약
- 수빈이는 현재 위치 N, 동생은 위치 K에 있고 수빈이가 이동할 수 있는 방법은 세 가지다
- X - 1 (1초 소요)
- X + 1 (1초 소요)
- X * 2 (0초 소요)
즉, 간선의 가중치가 0 또는 1인 그래프 최단거리 문제인데 일반 BFS로는 가중치 차이를 반영할 수 없기 때문에, 덱을 이용한 0-1 BFS가 필요합니다.
덱(deque)
- Double Ended Queue의 줄임말 → “앞뒤 양쪽에서 넣고 뺄 수 있는 큐”
- std::deque 로 C++ STL에서 제공
- 특징:
- push_front() / pop_front() → 앞에서 삽입·삭제
- push_back() / pop_back() → 뒤에서 삽입·삭제
- 즉, 스택(stack)과 큐(queue)의 장점을 합쳐 놓은 자료구조
덱을 왜 쓰나?
- 양쪽 삽입/삭제가 모두 O(1) → 빠름
- 상황에 따라 “앞에서 넣을지, 뒤에서 넣을지” 선택 가능
- 그래서 0-1 BFS 같은 문제에서 매우 유용
- 가중치 0 → push_front() (바로 처리)
- 가중치 1 → push_back() (한 단계 뒤 처리)
접근법
- 가중치가 0인 간선 → push_front()
- 가중치가 1인 간선 → push_back()
이렇게 하면 덱의 앞쪽에는 항상 "더 빨리 도달할 수 있는 위치"가 들어오게 되고, 최단 시간이 자연스럽게 보장된다
작성코드
#include <bits/stdc++.h>
using namespace std;
int N,K;
int BFS (void);
int main (void){
cin >> N >> K;
auto a = BFS();
cout << a;
return 0;
}
int BFS (void){
vector<int> distance(100001,1000000);
deque<int> dq;
dq.push_back(N);
distance[N] = 0;
while(!dq.empty()){
int x = dq.front();
dq.pop_front();
if (x == K) break;
int nx = x*2;
if(nx <= 100000 && distance[x] < distance[nx]){
distance[nx] = distance[x];
dq.push_front(nx);
}
for(int next : {x-1,x+1}){
if (0 > next || next > 100000) continue;
if(distance[next] > distance[x] + 1){
distance[next] = distance[x] + 1;
dq.push_back(next);
}
}
}
return distance[K];
}'매일 BOJ' 카테고리의 다른 글
| (매일 BOJ) C++ 16953번 A -> B (2) | 2025.08.27 |
|---|---|
| (매일 BOJ) C++ 13913번 숨바꼭질 4 (4) | 2025.08.22 |
| (매일 BOJ) C++ 3733번 Shares (0) | 2025.08.21 |
| (매일 BOJ) C++ 12851번 숨바꼭질 2 (0) | 2025.08.19 |
| (매일 BOJ) C++ 1697번 숨바꼭질 (2) | 2025.08.18 |