https://www.acmicpc.net/problem/13549
🚩최단 경로
최단 경로 문제였고, 각 동작에 따른 가중치가 다르기 때문에(+1과 -1은 가중치가 1이고, *2는 가중치가 0) 다익스트라 알고리즘으로 접근하였습니다. 또한, 가중치가 낮은 순서대로 실행하기 위해 Queue 대신 우선순위 큐를 사용했습니다.
아래는 우선순위 큐로 제출한 코드입니다.
import java.io.*;
import java.util.*;
class Node {
int num;
int depth;
public Node(int num, int depth) {
this.num = num;
this.depth = depth;
}
}
class Main {
static int K;
static boolean[] visited;
static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
visited = new boolean[100_001];
bfs(N, 0);
bw.write(min + "");
bw.close();
}
public static void djs(int num, int depth) {
PriorityQueue<Node> queue = new PriorityQueue<>((o1, o2) -> o1.depth - o2.depth);
queue.add(new Node(num, depth));
visited[num] = true;
while (!queue.isEmpty()) {
Node now = queue.poll();
visited[now.num] = true;
if (now.num == K) {
min = Math.min(min, now.depth);
}
if (now.num * 2 <= 100_000 && !visited[now.num * 2]) {
queue.add(new Node(now.num * 2, now.depth));
}
if (now.num + 1 <= 100_000 && !visited[now.num + 1]) {
queue.add(new Node(now.num + 1, now.depth + 1));
}
if (now.num - 1 >= 0 && !visited[now.num - 1]) {
queue.add(new Node(now.num - 1, now.depth + 1));
}
}
}
}
🤔 Queue vs PriorityQueue
문제를 풀고 나서 생각해 보니, 우선순위 큐를 사용할 경우 순간이동 시 depth가 0이기 때문에 순간이동 경로를 모두 탐색한 후에 다음 경로가 진행된다는 점을 알게 되었습니다. 이런 상황에서는 일반 Queue를 사용하는 것도 좋은 방법일 것 같아, Queue로 코드를 다시 작성해 보고 PriorityQueue와 비교해 보았습니다.
아래는 Queue를 이용한 제출 코드입니다.
import java.io.*;
import java.util.*;
class Node {
int num;
int depth;
public Node(int num, int depth) {
this.num = num;
this.depth = depth;
}
}
class Main {
static int K;
static boolean[] visited;
static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
visited = new boolean[100_001];
bfs(N, 0);
bw.write(min + "");
bw.close();
}
public static void bfs(int num, int depth) {
Queue<Node> queue = new LinkedList<>();
queue.add(new Node(num, depth));
visited[num] = true;
while (!queue.isEmpty()) {
Node now = queue.poll();
if (now.num == K) {
min = Math.min(min, now.depth);
}
if (now.num * 2 <= 100_000 && !visited[now.num * 2]) {
queue.add(new Node(now.num * 2, now.depth));
visited[now.num * 2] = true;
}
if (now.num - 1 >= 0 && !visited[now.num - 1]) {
queue.add(new Node(now.num - 1, now.depth + 1));
visited[now.num - 1] = true;
}
if (now.num + 1 <= 100_000 && !visited[now.num + 1]) {
queue.add(new Node(now.num + 1, now.depth + 1));
visited[now.num + 1] = true;
}
}
}
}
Queue를 사용했을 때, 실행 시간이 더 빠르고 메모리 사용량도 더 적다는 점을 확인할 수 있었습니다!
'Algorithm' 카테고리의 다른 글
[백준] 16139 : 인간-컴퓨터 상호작용 (JAVA) (0) | 2024.12.02 |
---|---|
[백준] 10816 : 숫자 카드 2 (JAVA) (0) | 2024.11.18 |
[백준] 1916 : 최소비용 구하기 (JAVA) (2) | 2024.11.13 |
[백준] 16953 : A -> B (JAVA) (1) | 2024.11.10 |
[백준] 11054 : 가장 긴 바이토닉 부분 수열 (JAVA) (1) | 2024.11.08 |