Algorithm

[BOJ] 13549. 숨바꼭질3

프로그래민 2020. 3. 15. 14:13
반응형

BFS를 사용하여 최단 시간을 찾는 문제이다.

이 문제는 일반 BFS와 다르게 풀어야 한다. 일반적인 BFS를 하기 위해선 모든 간선의 가중치가 동일해야 한다는 전제 조건이 필요하다. 그러나 이문제는 가중치가 0이 존재하므로 단순한 BFS를 사용할 수 없고, 다음과 같은 방법으로 풀수 있다.
- 다익스트라 알고리즘 : 모든 간선이 다를 경우 사용하기 용이
- 0-1 BFS : 가중치가 0인 간선에 연결된 정점은 큐의 맨뒤가 아닌 맨앞에 넣는 방법
- *2 를 별도의 간선으로 생각하지 않고, +1이나 -1에 의한 좌표의 2의 거듭제곱 배인 좌표들을 전부 큐에 넣는 방법

이 문제에선 간선이 0, 1 두가지 종류여서 다익스트라 알고리즘 보단 Deque을 이용하여 가중치가 0일 때, Deque의 addFirst해주는 방식으로 풀었다. 또한, 3가지 경우중 가중치가 0인 경우를 가장 먼저 해주어야 한다. visit배열을 이용하여 최단거리를 저장하였다.

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
76
77
78
package chap05;
 
 
public class Main_bj_13549_숨바꼭질3_re {
    
    static int start;
    static int dest;
    
    static int[] visit;
    static Deque<Pos> deque;
    
    static class Pos{
        int loc;
        int sec;
        public Pos(int l,int s) {
            loc=l;sec=s;
        }
    }
    
    
    public static void main(String[] args) throws Exception {
        
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        start= Integer.parseInt(st.nextToken());
        dest= Integer.parseInt(st.nextToken());
    
        deque = new LinkedList<>();
        visit= new int[100001];
        for(int i=0;i<100001;i++)
            visit[i]=-1;
        bfs();
        System.out.println(visit[dest]);
    }
    
    static void bfs() {
        deque.add(new Pos(start, 0));
        visit[start]=0;
        
        while(!deque.isEmpty()) {
            Pos cur = deque.poll();
            
            int first = cur.loc*2;
            if(first>=0 && first<=100000) {
                if(visit[first]==-1) {
                    deque.addFirst(new Pos(first, cur.sec));
                    visit[first]=cur.sec;
                }
            }
            
            int second = cur.loc-1;
            if(second>=0 && second<=100000) {
                if(visit[second]==-1) {
                    deque.addLast(new Pos(second, cur.sec+1));
                    visit[second]=cur.sec+1;
                }
            }
            
            int third = cur.loc+1;
            if(third>=0 && third<=100000) {
                if(visit[third]==-1) {
                    deque.addLast(new Pos(third, cur.sec+1));
                    visit[third]=cur.sec+1;
                }
            }
            
            
        }
        
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
                                                

 

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
package algostudy3;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.StringTokenizer;
 
public class Main_bj_13549_숨바꼭질3 {
    static int start, end;
    static int[] visit;
    static Deque<Integer> deque;
 
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
 
        start = Integer.parseInt(st.nextToken());
        end = Integer.parseInt(st.nextToken());
 
        visit = new int[100001];
        for (int i = 0; i <= 100000; i++) {
            visit[i] = -1;
        }
        deque = new LinkedList<>();
 
        bfs();
 
        System.out.println(visit[end]);
    }
 
    static void bfs() {
        deque.add(start);
        visit[start] = 0;
 
        while (!deque.isEmpty()) {
            int cur = deque.poll();
 
            if (cur == end) {
                break;
            }
 
            int next = 0;
 
            next = cur * 2;
            if (0 <= next && next <= 100000 && visit[next] == -1) {
                visit[next] = visit[cur];
                deque.addFirst(next);
            }
 
            next = cur - 1;
            if (0 <= next && next <= 100000 && visit[next] == -1) {
                visit[next] = visit[cur] + 1;
                deque.addLast(next);
            }
 
            next = cur + 1;
            if (0 <= next && next <= 100000 && visit[next] == -1) {
                visit[next] = visit[cur] + 1;
                deque.addLast(next);
            }
        }
    }
}
 
             
반응형

'Algorithm' 카테고리의 다른 글

[BOJ] 12851. 숨바꼭질2  (0) 2020.03.18
[BOJ] 1600. 말이 되고픈 원숭이  (0) 2020.03.18
[BOJ] 2206. 벽 부수고 이동하기  (0) 2020.03.15
[BOJ] 7576. 토마토  (2) 2020.03.10
[SWEA] 7793. 오! 나의 여신님  (0) 2020.03.10