1. 문제
https://www.acmicpc.net/problem/13549
13549번: 숨바꼭질 3
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일
www.acmicpc.net
2. 풀이 과정
[방법1] PriorityQueue를 이용한 BFS
도착 지점이 출발 지점보다 작은 경우, 빼기만 해서 가는 것이 가장 빠르므로 N-K를 출력한다.
아닌 경우는 PriorityQueue를 써서, 현재 최소 경로인 값에 +1, -1, *2 를 해본다.
더보기
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int K = Integer.parseInt(inputs[1]);
if(K <= N){
System.out.println(N-K);
}
else{
boolean[] visited = new boolean[100_001];
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2)->o1[1]-o2[1]);
pq.add(new int[]{N, 0});
while(!pq.isEmpty()){
int[] now = pq.poll();
if(now[0] == K){
System.out.println(now[1]);
break;
}
visited[now[0]] = true;
if(now[0] - 1 >= 0 && !visited[now[0] - 1]){
pq.add(new int[]{now[0] - 1, now[1] + 1});
}
if(now[0] + 1 <= 100000 && !visited[now[0] + 1]){
pq.add(new int[]{now[0] + 1, now[1] + 1});
}
if(now[0] * 2 <= 100000 && !visited[now[0]*2]){
pq.add(new int[]{now[0]*2, now[1]});
}
}
}
}
}
결과
[방법2] DP
짝수면, 자기 앞에서 +1해서 올 경우와 *2해서 올 경우만 고려하면 된다. 자기 바로 뒤의 값은 홀수이기 때문이다.
짝수가 아닐 경우, 자기 앞에서 +1해서 올 경우와 자기 뒤에서 -1해서 올 경우 2가지 중 최소를 구하면 된다.
i+1번째 수는 dp[i]+1이나 dp[(i+1)/2] 중에 최소를 고려하므로 i번째에서는 전자보다는 무조건 작을 것이므로 후자만 고려해주면 된다. 따라서 식은 Math.min(dp[i-1] + 1, dp[(i+1)/2] + 1)이 된다.
더보기
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int K = Integer.parseInt(inputs[1]);
int[] dp = new int[K+1];
if(K <= N){
System.out.println(N-K);
}
else{
for(int i=0; i<N; i++){
dp[i] = N-i;
}
for(int i=N+1; i<=K; i++){
if(i%2==0){
dp[i] = Math.min(dp[i/2], dp[i-1] + 1);
}
else{
dp[i] = Math.min(dp[i-1] + 1, dp[(i+1)/2] + 1);
}
}
System.out.println(dp[K]);
}
}
}
결과
'코딩문제풀이 > Baekjoon' 카테고리의 다른 글
[Java] 백준 6087번 : 레이저 통신 (0) | 2023.02.27 |
---|---|
[Java] 백준 1406번 : 에디터* (0) | 2023.02.25 |
[Java] 백준 10836번 : 여왕벌 (0) | 2023.02.20 |
[Java] 백준 16953번 : A -> B (0) | 2023.02.17 |
[Java] 백준 14722번 : 우유 도시 (0) | 2023.02.15 |