λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
μ•Œκ³ λ¦¬μ¦˜

[Java] BOJ 1697 μˆ¨λ°”κΌ­μ§ˆ

by 🍊귀🍊 2024. 8. 20.

문제 

문제 링크 https://www.acmicpc.net/problem/1697

  • μˆ˜λΉˆμ΄λŠ” 동생과 μˆ¨λ°”κΌ­μ§ˆμ„ ν•˜κ³  μžˆλ‹€. μˆ˜λΉˆμ΄λŠ” ν˜„μž¬ 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 μžˆλ‹€. 
  • μˆ˜λΉˆμ΄λŠ” κ±·κ±°λ‚˜ μˆœκ°„μ΄λ™μ„ ν•  수 μžˆλ‹€. λ§Œμ•½, 수빈이의 μœ„μΉ˜κ°€ X일 λ•Œ κ±·λŠ”λ‹€λ©΄ 1초 후에 X-1 λ˜λŠ” X+1둜 μ΄λ™ν•˜κ²Œ λœλ‹€. μˆœκ°„μ΄λ™μ„ ν•˜λŠ” κ²½μš°μ—λŠ” 1초 후에 2*X의 μœ„μΉ˜λ‘œ μ΄λ™ν•˜κ²Œ λœλ‹€.
  • μˆ˜λΉˆμ΄μ™€ λ™μƒμ˜ μœ„μΉ˜κ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, μˆ˜λΉˆμ΄κ°€ 동생을 찾을 수 μžˆλŠ” κ°€μž₯ λΉ λ₯Έ μ‹œκ°„μ΄ λͺ‡ 초 후인지 κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.
  • 첫 번째 쀄에 μˆ˜λΉˆμ΄κ°€ μžˆλŠ” μœ„μΉ˜ Nκ³Ό 동생이 μžˆλŠ” μœ„μΉ˜ Kκ°€ 주어진닀. Nκ³Ό KλŠ” μ •μˆ˜μ΄λ‹€.
  • μˆ˜λΉˆμ΄κ°€ 동생을 μ°ΎλŠ” κ°€μž₯ λΉ λ₯Έ μ‹œκ°„μ„ 좜λ ₯ν•œλ‹€.

아이디어

  • μ΅œμ†Œ μ‹œκ°„μ„ κ΅¬ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ μ΅œλ‹¨ 거리λ₯Ό κ΅¬ν• λ•Œ μ“°λŠ” BFSλ₯Ό 썼닀.
  • BFSλ₯Ό μ¨μ„œ Queue에 λ“€μ–΄μžˆλŠ” 값을 λΉΌλ‚΄μ„œ ν•΄λ‹Ή 값을 κΈ°μ€€ μ’Œν‘œλ‘œ 두고 이동 κ°€λŠ₯ν•œ μ’Œν‘œκ°€ λ°©λ¬Έν•˜μ§€ μ•Šμ•˜κ³  λ²”μœ„λ₯Ό λ„˜μ–΄κ°€μ§€ μ•ŠλŠ”λ‹€λ©΄ κΈ°μ€€ μ’Œν‘œ μ‹œκ°„μ— 1을 λ”ν•œ 값을 ν•΄λ‹Ή μ’Œν‘œ μ‹œκ°„ 배열에 μ €μž₯ν•œλ‹€.
  • 그리고 λ°©λ¬Έ 처리 ν›„, κ·Έ μ’Œν‘œκ°’μ„ Queue에 μ €μž₯ν•œλ‹€.
  • λ§Œμ•½ Queueμ—μ„œ 꺼낸값이 λͺ©μ  μ’Œν‘œμ™€ κ°™λ‹€λ©΄ μ’…λ£Œν•œλ‹€.

κ²ͺ은 μ‹œν–‰μ°©μ˜€

  • μ²˜μŒμ— DP라고 μƒκ°ν•˜κ³  ν’€λ €κ³  ν•΄λ΄€λŠ”λ° DPλ₯Ό ν‘ΈλŠ” 방식인 λΆ€λΆ„ 문제 κ²°κ³Όκ°’μœΌλ‘œ 좔둠을 ν•  μˆ˜κ°€ μ—†λ‹€κ³  νŒλ‹¨μ΄ λ˜μ—ˆλ‹€.
  • κ·Έλž˜μ„œ μ–΄μ œ ν’€μ—ˆλ˜ μ΅œλ‹¨ 거리λ₯Ό κ΅¬ν• λ•ŒλŠ” BFSλ₯Ό μ“°λ‹ˆκΉŒ μ΅œμ†Œ μ‹œκ°„λ„ λΉ„μŠ·ν•˜μ§€ μ•Šμ„κΉŒ ν•΄μ„œ BFS둜 ν’€μ—ˆλ‹€
  • 그리고 ArrayIndex μ—λŸ¬κ°€ λ‚¬λŠ”λ°.... λ²”μœ„λ₯Ό μ‹€μˆ˜λ‘œ 잘λͺ»μ§€μ •ν•΄μ„œ ν‹€λ Έμ—ˆλ‹€ γ…œγ…œ (μ‹€μˆ˜ 쑰심...!)

BFSλ₯Ό μ΄λŸ°μ‹μœΌλ‘œ μ‚¬μš©ν•΄μ„œ ν’€ μˆ˜λ„ μžˆλ‹€λŠ” 것을 μ•Œκ²Œ λ˜μ–΄μ„œ μ’‹μ•˜λ‹€!

μ½”λ“œ

import java.io.*;
import java.util.*;

public class BOJ1697 {

    static int N;
    static int K;
    static int time[];
    static boolean visited[];

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());

        // μˆ˜λΉˆμ΄κ°€ μžˆλŠ” μœ„μΉ˜
        N = Integer.parseInt(st.nextToken());
        // 동생이 μžˆλŠ” μœ„μΉ˜
        K = Integer.parseInt(st.nextToken());

        // κ±Έλ¦¬λŠ” μ‹œκ°„μ„ μ €μž₯ν•  λ°°μ—΄
        time = new int[100001];

        // λ°©λ¬Έ μ—¬λΆ€ 체크
        visited = new boolean[100001];

        BFS(N, K);

        System.out.println(time[K]);
    }

    public static void BFS(int x, int y){
        Queue<Integer> q = new LinkedList<>();

        q.offer(x);

        // μ‹œμž‘ 지점을 λ°©λ¬Έ 처리
        visited[x] = true;

        // μ‹œμž‘μ§€μ μ—μ„œ μ‹œμž‘μ§€μ κΉŒμ§€ κ±Έλ¦¬λŠ” μ‹œκ°„μ€ 0μ΄λ―€λ‘œ 0으둜 μ΄ˆκΈ°ν™”
        time[x] = 0;

        // Queueκ°€ λΉŒλ•ŒκΉŒμ§€ 반볡
        while(!q.isEmpty()){
            int n = q.poll();

            // ν˜„μž¬ μœ„μΉ˜μ™€ 도착 μœ„μΉ˜κ°€ κ°™λ‹€λ©΄ 반볡문 μ’…λ£Œ
            if(n == y){
                break;
            }

            // μ΄λ™ν•œ μ’Œν‘œλ₯Ό μ €μž₯ν•  λ°°μ—΄
            int move[] = {n - 1, n + 1, n * 2};

            // μ΄λ™ν•œ μ’Œν‘œλ“€ 즁
            for(int i : move){
                // λ²”μœ„λ₯Ό λ„˜μ–΄κ°€λ©΄ continue
                if(i < 0 || i > 100000){
                   continue;
                }

                // λ°©λ¬Έν•˜μ§€ μ•Šμ€ μ’Œν‘œκ°€ μžˆλ‹€λ©΄
                if(!visited[i]){
                    // ν•΄λ‹Ή μ’Œν‘œμ˜ μ‹œκ°„μ„ κΈ°μ€€ μ‹œκ°„ + 1둜 μ €μž₯ν•˜κ³ 
                    time[i] = time[n] + 1;
                    // λ°©λ¬Έ 처리 ν›„
                    visited[i] = true;
                    // Queue에 λ„£μŒ
                    q.offer(i);
                }
            }
        }
    }
}