https://www.acmicpc.net/problem/13549
13549번: 숨바꼭질 3
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때
www.acmicpc.net
13549번: 숨바꼭질3
BFS를 이용하여 풀 수도 있고, 다익스트라로 풀 수 있는 문제이다.
아래 코드는 다익스트라로 푼 것이다.
기존의 다익스트라 코드에서
앞 뒤로 한 칸 이동과 두 배로 이동하는 것을 각각 구현하여 코드 가독성을 높여보았다.
문제를 보면 숫자 한 칸 간격으로 무향 간선으로 이어져 있고, 각 숫자의 두 배의 숫자에 유향 간선이 있다.
4 →2 처럼 반대로 가는 경우는 없다.
위 그림과 같은 상태로 쭉 이어진다고 생각하면 다익스트라로 충분히 해결할 수 있다.
따로 vector<pair<int, int> > graph[100001];
같이 간선 정보를 넣을 필요없이
다익스트라 알고리즘 안에 정보를 넣는다면 더욱 간편하게 코드를 짤 수 있다.
N이 K보다 큰 경우가 있을 수 있어서 조건문으로 앞에서 바로 처리할 수 있게 했다.
(테스트 시간에는 영향이 없는 듯 하다.
#include <bits/stdc++.h>
#define INF 100010
using namespace std;
int N, K;
vector<int> dist(100001, INF);
void dijkstra(int start) {
dist[start] = 0;
priority_queue<pair<int, int> > pq;
pq.push({0, start});
while(!pq.empty()) {
int cost = -pq.top().first;
int here = pq.top().second;
pq.pop();
if(dist[here] < cost) continue;
if (here + 1 <= 100000) {
if (cost + 1 < dist[here + 1]) {
dist[here + 1] = cost + 1;
pq.push({-(cost+1), (here + 1)});
}
}
if (here - 1 >= 0) {
if (cost + 1 < dist[here - 1]) {
dist[here - 1] = cost + 1;
pq.push({-(cost+1), (here - 1)});
}
}
if (here * 2 <= 100000) {
if (cost < dist[here * 2]) {
dist[here * 2] = cost;
pq.push({-cost, (here * 2)});
}
}
}
}
int main(void) {
cin >> N >> K;
if (N >= K) {
cout << N - K;
return 0;
} else {
dijkstra(N);
cout << dist[K];
return 0;
}
}
'알고리즘 > 최단 경로' 카테고리의 다른 글
(c++) 벨만-포드 알고리즘 11657번: 타임머신 (2) | 2024.01.09 |
---|---|
(c++) 플로이드 워셜 알고리즘 11404번: 플로이드 (1) | 2024.01.07 |
(c++) 다익스트라 9370번: 미확인 도착지 (1) | 2024.01.06 |
(c++) 다익스트라 문제 1504번: 특정한 최단 경로 (1) | 2024.01.03 |
(c++)다익스트라 알고리즘 - 1753번 : 최단경로 (1) | 2024.01.02 |
댓글