넘치게 채우기
[BOJ] 13549 - 숨바꼭질 3 본문
https://www.acmicpc.net/problem/13549
BOJ - 숨바꼭질 3
문제 유형: 다익스트라
문제 난이도: Gold V
시간 제한: 2초
메모리 제한: 512MB
문제
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 0초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
풀이
dist배열을 전체 수의 범위에 대해 만든다.
dist[i]는 n부터 i까지의 최소시간이다.
dist[n]은 0으로 해둔다.
향상된 다익스트라를 이용하여 탐색한다.
만약 현재 노드와 현재 브랜치의 가중치가 dist[현재노드]를 넘으면, 빠른 종료한다.
그게 아니라면,
자신의 현재 수에서 -1, +1, *2가 각각 유효하고 예상 시간이 줄어든다면, 탐색한다.
각각 {curr_cost+1, curr_pos-1}, {curr_cost+1, curr_pos+1}, {curr_cost, curr_pos * 2}를 pq에 넣는다.
최종적으로 dist[k]를 반환한다.
코드
C++
#include <bits/stdc++.h>
using namespace std;
int n, k;
int dist[100001];
int main(int argc, char *argv[]) {
cin >> n >> k;
fill_n(dist, 100001, INT_MAX);
priority_queue<pair<int, int>, vector<pair<int, int>>,
greater<pair<int, int>>>
pq;
pq.push({0, n});
dist[n] = 0;
while (!pq.empty()) {
auto curr = pq.top();
pq.pop();
if (dist[curr.second] < curr.first)
continue;
if (curr.second - 1 >= 0 && curr.first + 1 < dist[curr.second - 1]) {
dist[curr.second - 1] = curr.first + 1;
pq.push({curr.first + 1, curr.second - 1});
}
if (curr.second + 1 < 100001 && curr.first + 1 < dist[curr.second + 1]) {
dist[curr.second + 1] = curr.first + 1;
pq.push({curr.first + 1, curr.second + 1});
}
if (curr.second * 2 < 100001 && curr.first < dist[curr.second * 2]) {
dist[curr.second * 2] = curr.first;
pq.push({curr.first, curr.second * 2});
}
}
cout << dist[k] << "\n";
return 0;
}
'PS > BOJ' 카테고리의 다른 글
[BOJ] 1043 - 거짓말 (0) | 2024.11.06 |
---|---|
[BOJ] 12865 - 평범한 배낭 (0) | 2024.11.04 |
[BOJ] 9251 - LCS (0) | 2024.11.03 |
[BOJ] 2096 - 내려가기 (0) | 2024.11.02 |
[BOJ] 17070 - 파이프 옮기기 1 (0) | 2024.11.01 |