[백준] 13913. 숨바꼭질 4 _ Java

jii0_0·2022년 9월 7일
0

Beakjoon Online Judge

목록 보기
5/22
post-thumbnail

숨바꼭질 4 (Gold IV)

문제 링크

문제 설명

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

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

입력

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

출력

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

둘째 줄에 어떻게 이동해야 하는지 공백으로 구분해 출력한다.

문제 풀이

  • 문제 해결은 숨바꼭질이랑 같았다 !
  • 지나온 경로를 저장하는 방법을 생각하는데 처음엔 StringBuilder를 배열로 만들어서 다 저장할까 싶었는데, 테스트케이스가 작은 숫자라 쉬운 느낌이지 큰 숫자라면 너무 커지고 복잡할 것 같았다
  • 그래서 바로 직전의 숫자를 저장해서 되짚어 나가면 될 것 같았다
  • int[] 배열을 만들고 bfs를 돌면서 이동할 인덱스에 이동 전 숫자를 저장했다
  • 그리고 bfs를 다 돌고나서 K인덱스에서 N이 나올때까지 stack에 값을 넣고 출력했다

Solution

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;

//숨바꼭질 4
public class Main {
	static int[] check = new int[100001];
	static int[] before = new int[100001];
	static int N;
	static int K;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		K = sc.nextInt();

		if (N == K) { // 입력이 같을 때
			System.out.println(0);
			System.out.println(N);
		} else {
			findK(N); // bfs
			StringBuilder sb = new StringBuilder(); // 결과 저장
			sb.append(check[K] + "\n");
			Stack<Integer> stack = new Stack<>();
			int after = K; // 뒤에서부터 왔던길 찾아가기
			while (after != N) {
				stack.push(after);
				after = before[after];
			}
			stack.push(N); // 마지막N까지 넣어주기

			while (!stack.isEmpty()) {
				sb.append(stack.pop()).append(" ");
			}

			System.out.println(sb.toString());

		}
	}

	public static void findK(int n) {
		Queue<Integer> que = new LinkedList<>(); // 큐 생성
		que.add(n);

		while (!que.isEmpty()) { // 큐가 빌때까지
			int X = que.poll(); // 현재 X
			if (X == K) // 값이 구해지면 스탑
				break;
			if (X > 0 && check[X - 1] == 0) { // X -1
				que.add(X - 1);
				check[X - 1] = check[X] + 1;
				before[X - 1] = X; // 이전에 들렀던 곳 저장
			}
			if (X + 1 < check.length && check[X + 1] == 0) { // X +1
				que.add(X + 1);
				check[X + 1] = check[X] + 1;
				before[X + 1] = X;
			}
			if (X * 2 < check.length && check[X * 2] == 0) { // X *2
				que.add(X * 2);
				check[X * 2] = check[X] + 1;
				before[X * 2] = X;

			}

		}
	}

}
profile
느려도 꾸준히

0개의 댓글