BOJ_숨바꼭질2 _12851 (Java)

융바오·2025년 1월 1일

Problem Solving

목록 보기
19/89

문제 링크

성능 요약

메모리: 24956 KB, 시간: 168 ms

분류

너비 우선 탐색, 그래프 이론, 그래프 탐색

제출 일자

2024년 12월 28일 21:38:39

문제 설명

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 그리고, 가장 빠른 시간으로 찾는 방법이 몇 가지 인지 구하는 프로그램을 작성하시오.

입력

첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

출력

첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

둘째 줄에는 가장 빠른 시간으로 수빈이가 동생을 찾는 방법의 수를 출력한다.

느낀점

  • 문제를 잘 읽자. 비슷한 문제라고 대충 읽고 추측하면 안된다. 조건이 달라지기 때문에 다른 문제인거다.
  • 문제 푸는 시간을 정해두고 집중하자..

설계 : 20분

  • 세가지 이동방식의 시간 경과 정도가 일정(즉, 가중치가 모두 동일)하기 때문에 다익스트라가 아닌 BFS로 구현 가능하다.
  • 경우의 수가 필요하지만 모든 경우를 다 돌면 메모이제이션을 사용하는 의미가 없다.
  • 이동시간을 기록하듯, 한 경로에 최소 이동시간으로 도착한 경우를 저장해서 다음 이동시에 카운트를 넘긴다. (경우의 수 연결)
  • 시간 기록 배열과 방문횟수 기록 배열이 필요하다.

코드(Java)

  • 구현 시간: 50분
/**
 * Author: yngbao97, Yuk Yejin
 * Problem: 숨바꼭질 2_12851
 * Date: 2024.12.28
 */

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

public class Main {
	static BufferedReader br;
	static BufferedWriter bw;
	static StringTokenizer st;

	public static void main(String[] args) throws Exception {

		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));

        String[] input = br.readLine().split(" ");
        int n = Integer.parseInt(input[0]);
        int k = Integer.parseInt(input[1]);

        int[] time = new int[150_000];
        int[] cnt = new int[150_000];
        Arrays.fill(time, 123456789);

        Queue<Integer> queue = new ArrayDeque<>();
        queue.offer(n);
        time[n] = 0;
        cnt[n] = 1;

        while(!queue.isEmpty()) {

            int curr = queue.poll();

            if (curr == k) break;

            int[] step = new int[] {curr - 1, curr + 1, curr * 2};

            for (int next : step) {
                if (next >= 0 && next < 150_000 && time[next] >= time[curr] + 1) {
                    if (time[next] == time[curr] + 1) cnt[next] += cnt[curr];
                    else {
                        time[next] = time[curr] + 1;
                        cnt[next] = cnt[curr];
                        queue.add(next);
                    }
                }
            }
        }

        bw.write(String.valueOf(time[k]) + "\n");
        bw.write(String.valueOf(cnt[k]));
		bw.flush();
		bw.close();
		br.close();
	}
}

0개의 댓글