BOJ 백준 13549 : 숨바꼭질 3
Updated:
시작하면서
이번 문제는 다익스트라 알고리즘(Dijkstra Algorithm) 을 사용해 해결하는 문제이다.
문제 이해
이 문제는 언뜻보면 다익스트라인지 아닌지 알기 애매한 문제이다. 노드와 간선이 제시되어 있지 않고, 단순히 이동해야 한다고 제시되어 있기 때문이다. 이 문제를 다음과 같이 해석해야 한다.
- 수빈이와 동생의 위치는 노드이다.
- 그러므로 노드가 0번부터 ~ 100,000번까지 있다고 생각하면 된다.
- 이때 100,000을 넘어가면 가장 빠른 시간이 되지 않고 더 늘어나기만 하므로, 문제에서 제시하지 않았지만 100,000 이상의 범위는 무시한다.
- 이동할 수 있는 경우의 수는 총 3가지로 x2, -1, +1이다.
- 해당 경우의 수로 이동하는 경로들이 모두 간선이다.
위와 같이 문제를 변경하고 최소 경로를 찾아간다. 방법은 다음과 같다.
-
현재 수빈이의 위치를 deque에 넣어준다.
-
현재 노드에서 이동할 수 있는 경우의 수들을 체크한다.
-
중요 : x2로 이동하는 경우는 시간이 올라가지 않으므로, 먼저 체크하기 위해 큐의 앞에 넣어주고, 한 칸씩 이동하는 경우는 큐의 뒤에 넣어준다.
-
0 ~ 100,000 사이에 있는지, 이미 방문한 점인지를 체크하고 조건에 만족하면 큐에 넣어준다.
-
-
계속 반복하면서 답을 찾는다.
해결
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
#define RANGE (100001)
bool IsOverNumer(int standard, int number)
{
if (number > 100000)
return true;
if (number < 0)
return true;
return false;
}
int GetAnswer(int N, int K)
{
if (N == K)
return 0;
vector<bool> visited(RANGE, false);
deque<pair<int, int>> q;
q.push_front(make_pair(N, false));
while (q.empty() == false)
{
int current = q.front().first;
int time = q.front().second;
if (current == K)
{
return time;
}
q.pop_front();
if (IsOverNumer(K, current * 2) == false && visited[current * 2] == false)
{
visited[current * 2] = true;
q.push_front(make_pair(current * 2, time));
}
if (IsOverNumer(K, current - 1) == false && visited[current - 1] == false)
{
visited[current - 1] = true;
q.push_back(make_pair(current - 1, time + 1));
}
if (IsOverNumer(K, current + 1) == false && visited[current + 1] == false)
{
visited[current + 1] = true;
q.push_back(make_pair(current + 1, time + 1));
}
}
return 0;
}
int main()
{
// sync off
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// sync off
int N, K;
cin >> N >> K;
cout << GetAnswer(N, K);
return 0;
}
Leave a comment