분류: bfs, 1차원 bfs, 재귀, dp /
문제
문제 설명
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 0초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
풀이
- 1차원 BFS
#include <iostream>
#include <queue>
using namespace std;
int dist[100001];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, K; cin >> N >> K;
queue<int> Q;
Q.push(N);
dist[N] = 1;
while(dist[K] == 0) {
int x = Q.front(); Q.pop();
for(int nx=2*x; nx<100001; nx *= 2) {
if(dist[nx]) break;
dist[nx] = dist[x];
Q.push(nx);
}
for(int nx:{x-1, x+1}) {
if(nx<0 || nx>100000) continue;
if(dist[nx]) continue;
dist[nx] = dist[x] + 1;
Q.push(nx);
}
}
cout << dist[K] - 1;
}
1차원 bfs
순간이동의 경우 가중치가 0이므로 가능한 모든 경우로 순간이동 하고 큐에 삽입
- 재귀 + 메모이제이션
#include <iostream>
using namespace std;
int dp[100001];
int N, K;
int move(int k) {
if(dp[k]) return dp[k];
if(N >= k) dp[k] = N - k;
else if(k == 1) dp[k] = 1;
else if(k & 1) dp[k] = min(move(k+1), move(k-1)) + 1;
else dp[k] = min(k-N, move(k/2));
return dp[k];
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> N >> K;
cout << move(K);
}
[백준 - 1697] 숨바꼭질 문제에서 가중치만 없앤 것과 같다.
'Problem Solving > BOJ' 카테고리의 다른 글
[백준 - 13913] 숨바꼭질 4 - C++ (0) | 2023.10.17 |
---|---|
[백준 - 20304] 비밀번호 제작 - C++ (0) | 2023.10.17 |
[백준 - 1600] 말이 되고픈 원숭이 - C++ (0) | 2023.10.16 |
[백준 - 2146] 다리 만들기 - C++ (0) | 2023.10.15 |
[백준 - 9466] 텀 프로젝트 - C++ (0) | 2023.10.13 |