[伯俊/1697]鬼ごっこ(Java)


Question


  • 質問リンク:https://www.acmicpc.net/problem/1697

  • 分類:BFS

  • 回答時間:30分
  • 問題の説明

  • スビンはN、弟はK(0<=N、K<=10000)
  • スビンは1秒以内にN-1、N+1の位置まで歩いたり、2*Nの位置まで瞬時に移動したりできる
  • スビンが歩いたりKポジションまで走ったりするのに少なくとも数秒かかる
  • Solution


    プールアクセス方法

  • N-1,N+1,N*2位置,BFS
  • 正しいコード

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.StringTokenizer;
    
    public class Main {
      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.valueOf(st.nextToken());
        int K = Integer.valueOf(st.nextToken());
    
        if (N == K) {
          bw.write(0 + "\n");
        } else {
          bw.write(bfs(N, K) + "\n");
        }
    
        bw.flush();
        bw.close();
    
      }
    
      static boolean isIn(int n) {
        if (0 <= n && n <= 100000) {
          return true;
        }
        return false;
      }
    
      static int bfs(int N, int K) {
        int minCnt = 987654321;
        boolean[] visited = new boolean[100001];
        Queue<int[]> queue = new LinkedList<int[]>();
    
        // [위치, 해당 위치로 도착한 초]
        queue.add(new int[] { N, 0 });
        visited[N] = true;
    
        while (!queue.isEmpty()) {
          int[] arr = queue.poll();
          int n = arr[0];
          int cnt = arr[1];
    
          // 다음 위치를 담은 배열
          int[] next = new int[] { n - 1, n + 1, n * 2 };
    
          for (int i = 0; i < 3; i++) {
            // 다음 위치가 도착 위치면 최소 초 갱신
            if (next[i] == K) {
              minCnt = Math.min(minCnt, cnt + 1);
              continue;
            }
    
            // 범위 안을 벗어나거나 이미 방문한 공간(더 작은 초에 방문해서 다시 안봐도 됨)이면 생략
            if (!isIn(next[i]) || visited[next[i]])
              continue;
    
            visited[next[i]] = true;
            queue.add(new int[] { next[i], cnt + 1 });
          }
        }
    
        return minCnt;
      }
    
    }