알고리즘 풀이/BFS(너비 우선 탐색)

BOJ 1600 [말이 되고픈 원숭이]

갓우태 2018. 9. 23. 04:21

BOJ 말이 되고픈 원숭이 : https://www.acmicpc.net/problem/1600






안녕하세요. 이번 문제는 백준 온라인 저지의 [말이 되고픈 원숭이] 입니다.


BFS를 단순하게 사용하면 풀릴 것 같지만, 함정이 있었습니다.


말처럼 움직였을때의 위치와, 그냥 한번 움직였을 때의 위치가 같을 경우에,


좌표가 같아도 그 경로가 다를 수 있습니다.





쉽게말해서 말의 움직임을 아껴놨다가 사용해야할 경우가 생길 수 있습니다.


하지만 먼저 기회를 사용해 해당 좌표에 도달한 것을 체크한다면,


나중에 기회를 아꼈을 경우 해당 좌표가 Visited되있어 재방문을 할 수 없습니다.


그래서 Visited를 3차원으로 만들었습니다.





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
import java.util.*;
class Node {
    public int i, j, depth, chance;
    Node(int i, int j, int depth, int chance) {
        this.i = i;
        this.j = j;
        this.depth = depth;
        this.chance = chance;
    }
}
public class Main {
    public static int K, W, H;
    public static int[][] Map = new int[200][200];
    public static boolean[][][] Visited = new boolean[200][200][31];
    public static Queue<Node> q = new LinkedList<Node>();
    public static int[][] d = { { -10}, {10}, {0-1}, {01} };
    public static int[][] horse_d = { {-2-1}, {-21}, {-12}, {12}, {21}, {2-1}, {1-2}, {-1-2} };
    public static boolean is_bound(int h, int w) {
        return h >= 0 && h < H && w >= 0 && w < W;
    }
    public static int BFS() {
        while(!q.isEmpty()) {
            Node node = q.poll();
            if(node.i == H-1 && node.j == W-1) {
                return node.depth;
            }
            for(int k = 0; k < 8; k++) {
                int next_i = node.i + horse_d[k][0];
                int next_j = node.j + horse_d[k][1];
                if(is_bound(next_i, next_j) && node.chance < K) {
                    if(!Visited[next_i][next_j][node.chance + 1&& Map[next_i][next_j] == 0) {
                        Visited[next_i][next_j][node.chance + 1= true;
                        Node new_node = new Node(next_i, next_j, node.depth + 1, node.chance + 1);
                        q.offer(new_node);
                    }
                }
            }
            for(int k = 0; k < 4; k++) {
                int next_i = node.i + d[k][0];
                int next_j = node.j + d[k][1];
                if(is_bound(next_i, next_j)) {
                    if(!Visited[next_i][next_j][node.chance] && Map[next_i][next_j] == 0) {
                        Visited[next_i][next_j][node.chance]= true;
                        Node new_node = new Node(next_i, next_j, node.depth+ 1, node.chance);
                        q.offer(new_node);
                    }
                }
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        K = sc.nextInt();
        W = sc.nextInt();
        H = sc.nextInt();
        for(int h = 0; h < H; h++) {
            for(int w = 0; w< W; w++) {
                Map[h][w] = sc.nextInt();
            }
}
        for(int k = 0; k <= K; k++)
            Visited[0][0][k] = true;
        Node first_node = new Node(0000);
        q.offer(first_node);
        System.out.println(BFS());
    }
}

cs



반응형