문제 풀이
간단하게 BFS로 작성하고 제출하면 틀렸다고 나온다.
수빈이는
0초에 순간이동으로 현재 지점 x -> 2x로 움직일 수 있고,
1초에 -1 혹은 1로 움직일 수 있다.
그런데 BFS 라는 알고리즘은 모든 간선의 가중치가 동일해야 한다는 전제 조건이 필요하기 때문이다.
이 문제 같은 경우는 동일하지 않은 가중치가 존재한다.
이러한 문제를 해결하기 위해서는 상식적으로 현재 공간에서 순간이동, 후진, 전진 중 시간 소모가 없는 순간이동부터 하는 것이 최단 경로다. 그런데 어떤 경우에서는 순간 이동보다 후진 혹은 전진이 먼저 큐에서 나올 수 있기 때문에
큐에 넣을 때 간선의 가중치가 훨씬 적은 순간이동부터 최우선으로 넣어야하는 것만 주의하면 된다.
이런 알고리즘을 0-1 BFS라고 한다.
0-1 BFS를 구현하는 방법은 여러가지가 있겠지만 deque를 이용해서 간단하게 구현할 수 있다.
가중치가 낮은 순간이동의 경우는 큐의 앞쪽에 넣고
가중치가 높은 후진이나 전진의 경우는 큐의 뒤쪽에 넣어서
최단 경로를 보장할 수 있도록 구현하면 문제를 해결할 수 있다.
소스 코드
#include <iostream>
#include <queue>
#include <deque>
using namespace std;
const int MAX = 200002;
int N, K;
bool visit[MAX];
int bfs()
{
deque<pair<int, int> > dq;
dq.emplace_back(N, 0);
visit[N] = true;
while (!dq.empty())
{
int cur = dq.front().first;
int cnt = dq.front().second;
dq.pop_front();
if (cur == K)
{
return cnt;
}
if (cur * 2 < MAX)
{
if (visit[cur * 2] == false)
{
visit[cur * 2] = true;
dq.emplace_front(cur * 2, cnt);
}
}
if (cur + 1 < MAX)
{
if (visit[cur + 1] == false)
{
visit[cur + 1] = true;
dq.emplace_back(cur + 1, cnt + 1);
}
}
if (cur - 1 >= 0)
{
if (visit[cur - 1] == false)
{
visit[cur - 1] = true;
dq.emplace_back(cur - 1, cnt + 1);
}
}
}
return -1;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N >> K;
cout << bfs() << endl;
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준 1197] 최소 스패닝 트리 (0) | 2021.11.17 |
---|---|
[백준 11779] 최소비용 구하기2 (0) | 2021.11.15 |
[백준 14503] 로봇 청소기 (0) | 2021.11.14 |
[백준 9205] 맥주 마시면서 걸어가기 (0) | 2021.11.13 |
[백준 6593] 상범 빌딩 (0) | 2021.11.11 |