ALGORITHM/BOJ

[백준] 13913 숨바꼭질 4

0298 2021. 7. 9. 13:22

https://www.acmicpc.net/problem/13913

 

13913번: 숨바꼭질 4

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

2021-07-09


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main13913 {
    public static int N, K;
    public static int[] dir = {-112};
    public static boolean[] vtd;
    public static int[] arr;
    public static Queue<Integer> q;
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        vtd = new boolean[100001];
        arr = new int[100001];
        q = new LinkedList<>();
        q.add(N);
        vtd[N] = true;
        int count = 0;
        Stack<Integer> s = new Stack<>();
        StringBuilder sb = new StringBuilder();
 
        if(N == K) {
            sb.append(N);
        } else {
            loop:while(!q.isEmpty()) {
                int size = q.size();
                while(size > 0) {
                    int xx = q.poll();
 
                    int nx = 0;
                    for(int i = 0; i < 3; i++) {
                        if(i == 2) {
                            nx = xx * dir[i];
                        } else {
                            nx = xx + dir[i];
                        }
 
                        if(nx < 0 || nx > 100000 || vtd[nx]) continue;
 
                        arr[nx] = xx;
                        if(nx == K) {
                            count++;
                            int start = nx;
                            s.push(nx);
                            while(start != N) {
                                s.push(arr[start]);
                                start = arr[start];
                            }
                            break loop;
                        }
                        vtd[nx] = true;
                        q.add(nx);
                    }
                    size--;
                }
                count++;
            }
        }
 
        while(!s.isEmpty()) {
            sb.append(s.pop()).append(" ");
        }
        System.out.println(count);
        System.out.println(sb.toString());
    }
}
 
cs

#문제풀이

 

BFS문제이다.

 

1) 처음에 List를 들고다니면서, 경로를 저장해줬었는데 시간초과가 났다. 

 

2) 두번째는 현재 시점의 바로 앞 경로만 따로 저장을 해주고, 마지막에 그 경로들을 다시 재탐색하면서 stringbuilder에 저장해줬다. 뒤집어서 해야해서,, insert를 썼었다. 그런데 여기서도 시간초과가 났었다. 

1
2
3
4
5
sb.append(nx);
while(start != N) {
   sb.insert(0, arr[start]).insert(String.valueOf(arr[start]).length(), " ");
   start = arr[start];
}
cs

 

3) 그래서 결국 경로 재탐색하면서 stack에 저장하고, 마지막으로 stack에 있는것들 pop하면서 stringbuilder에 append 하는 방식으로 처리했다.