문제
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 0초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
이 문제가 우선순위큐를 써야하는 이유는 queue나 Node,vecector를 사용하는 문제와는 달리 이동에 소요되는 count값이 다르기 때문이다. 다른 값은 2배 점프나 1칸 이동이나 전부 1의 시간이 같이 소요되므로 어떤 지점에 도달한다고 했을때 한 점에 도달한 시간이 당연히 최소의 시간이 되는 것인데 그니까 카운트 2가 카운트 3보다 늦게 저장될 수 가 없음. 그런데 이 문제는 0의 카운트를 세는 경우가 존재하므로 그거 부터 파생되는 카운트 값들이 제각각이 되어 카운트 2가 카운트 3보다 늦게 저장되는 경우가 가능 (1 1 1 과 0 0 1 1 과 같은경우)
따라서 우선순위 큐를 이용해서 카운트 순서대로 정렬 해 줘야함. 그리고 그과정에서 메모리 초과가 없기 위해 visit를 사용하는데 0의 경우가 더 먼저 저장되도록 if문의 순서를 조정
#include <iostream>
#include <queue>
using namespace std;
int N,K;
bool visit[100001];
priority_queue<pair<int, int> , vector<pair<int,int> > ,greater<pair<int,int> > > pr;
int main(void)
{
cin >> N >> K;
pr.push({0,N});
visit[N]= true;
while(!pr.empty())
{
int count = pr.top().first;
int now = pr.top().second;
pr.pop();
if(now == K)
{
cout<< count<<endl;
break;
}
else
{
if(!visit[now*2] &&now*2>=0 && now*2<=100000)
{
visit[now*2] = true;
pr.push({count,now*2});
}
if(!visit[now+1]&& now+1>=0 && now+1<=100000)
{
visit[now+1] = true;
pr.push({count+1,now+1});
}
if(!visit[now-1]&& now-1>=0 && now-1<=100000)
{
visit[now-1] = true;
pr.push({count+1,now-1});
}
}
}
}
'Algorithm' 카테고리의 다른 글
백준 2887번 행성 터널 (0) | 2019.08.29 |
---|---|
백준 4195번 친구네트워크 (0) | 2019.08.28 |
백준 2178번 미로 탐색 (0) | 2019.08.26 |
백준 12761번 돌다리 (0) | 2019.08.25 |
백준 1411번 비슷한 단어 (0) | 2019.08.24 |