[백준] 13549 : 숨바꼭질 3 (JAVA)

2024. 11. 5. 15:08·Algorithm

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
'Algorithm' 카테고리의 다른 글
  • [백준] 10816 : 숫자 카드 2 (JAVA)
  • [백준] 1916 : 최소비용 구하기 (JAVA)
  • [백준] 16953 : A -> B (JAVA)
  • [백준] 11054 : 가장 긴 바이토닉 부분 수열 (JAVA)
chanyoungdev
chanyoungdev
chanyoungdev
  • chanyoungdev
    Young Code
    chanyoungdev
  • 전체
    오늘
    어제
    • 분류 전체보기 (28)
      • Programming (12)
        • Java (0)
        • Spring (10)
        • etc (2)
      • Data Infra (5)
        • Database (1)
        • Redis (2)
        • etc (2)
      • DevOps (4)
        • CI CD (1)
        • Nginx (2)
        • Docker (0)
        • Aws (0)
        • etc (1)
      • Algorithm (6)
      • etc (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • First Tech Blog
    • Github
  • 공지사항

  • 인기 글

  • 태그

    Mockito
    nginx
    Algorithm
    lock
    junit
    spring security
    Spring Batch
    elasticsearch
    OAuth
    cache
    ssl
    캐시
    Infra
    JWT
    공통 응답
    domain
    infra architecture
    Virtual Thread
    단위 테스트
    Redis
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
chanyoungdev
[백준] 13549 : 숨바꼭질 3 (JAVA)
상단으로

티스토리툴바