👀 문제 설명
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 0초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
예제 입력 1
5 17
예제 출력 1
2
✍🏻풀이
BOJ 1697 숨바꼭질과 비슷한 문제이다.
큐를 사용해서 문제를 풀면 되는데, 순간이동을 하는 경우에는 시간이 늘어나지 않으므로 우선순위 큐를 사용해야 정확한 답이 나온다.
우선순위큐를 사용해 이동시간이 짧은 순서대로 이동한다.
이 때, 우선순위큐를 오름차순으로 정렬하려면 priority_queue<자료형, 구현체, greater>로 정의해야 한다.
자료형은 int, double, pair 등등이고,
구현체는 기본적으로 vector<자료형>으로 정의된다. 이 말은 priority_queue가 실제로는 vector 위에서 돌아가고 있다는 것이다.
비교 연산자는 less<자료형> 또는 greater<자료형>을 사용하면 된다.
코드
#include <stdio.h>
#include <iostream>
#include <queue>
#define MAX 100001
using namespace std;
bool visit[MAX];
int main() {
ios::sync_with_stdio(0);
cin.tie(NULL); cout.tie(NULL);
int N, K;
cin >> N >> K;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> Q;
Q.push({ 0, N });
visit[N] = true;
while (!Q.empty()) {
int curTime = Q.top().first;
int curLoc = Q.top().second;
Q.pop();
if (curLoc == K) {
cout << curTime << "\n";
break;
}
for (int next : { curLoc + 1, curLoc - 1, 2 * curLoc }) {
if (0 <= next && next < MAX && visit[next] == false) {
visit[next] = true;
if (next == 2 * curLoc) {
Q.push({ curTime, next });
}
else {
Q.push({ curTime + 1, next });
}
}
}
}
return 0;
}
'숨막히는 알고말고 > 문제 풀이' 카테고리의 다른 글
[Baekjoon] 좌표 정렬하기 2 (0) | 2021.03.08 |
---|---|
[Baekjoon] 체스판 다시 칠하기 (2) | 2021.03.06 |
[Baekjoon] 하얀 칸 (0) | 2021.03.04 |
[Baekjoon] 저항 (0) | 2021.03.03 |
[Baekjoon] 빵집 (0) | 2021.03.01 |