탈출




물이 인접한 칸으로 계속 불어날 때, 고슴도치가 물에 닿지 않고 목표지점까지 갈 수 있는지,

간다면 최단거리는 몇인지 알아내야 한다.


그래프 탐색문제이며, 최단거리를 알아내야 하므로 BFS를 써보기로 했다.

물과 고슴도치를 모두 큐에 넣고 BFS를 돌려버릴 수 있겠다.

하지만 둘 다 같은 시간에 같은 칸에 도착한다면 물이 이기는 경우를 처리할 수 없다.(내 생각에는)


그래서 물은 고슴도치의 이동에 전혀 영향을 받지 않으므로,

물만 BFS를 먼저 돌려서 언제 어디까지 불어나는지를 먼저 확인하자.

이 후 고슴도치는 물이 어떻게 불어나는지 저장된 지도를 보고 도착지점까지 BFS로 도착하면 된다.


코드로 옮기면 다음과 같다.

요새 STL을 쓰지 않는 연습을 하고 있는지라, 코드가 매우 길다.


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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <stdio.h>
 
typedef struct col {
    int x, y;
}col;
 
col que[10000];
int que_front, que_back;
#define que_size 10000
void que_push(int x, int y) {
    que[que_back] = { x,y };
    que_back = (que_back + 1) % que_size;
}
col que_pop() {
    col tmp = que[que_front];
    que_front = (que_front + 1) % que_size;
 
    return tmp;
}
 
char buf[51];
int r, c;
int map[50][50];
int waters_cnt;
col waters[2500];
col start, dst;
 
int dir[4][2= { { 1,0 },{ 0,1 },{ -1,0 },{ 0,-1 } };
int abs(int x) {
    return x > 0 ? x : -x;
}
 
void water_bfs() {
    int cnt = 2;
 
    while (que_front != que_back) {
        int size = abs(que_back - que_front);
 
        while (size--) {
            col tmp = que_pop();
 
            for (int i = 0; i < 4++i) {
                int xx = tmp.x + dir[i][0];
                int yy = tmp.y + dir[i][1];
 
                if (xx < 0 || yy < 0 || xx >= r || yy >= c)
                    continue;
 
                if (map[xx][yy] != 0)
                    continue;
 
                que_push(xx, yy);
                map[xx][yy] = cnt;
            }
        }
        cnt++;
    }
}
 
int beaber_bfs() {
    int cnt = 2;
 
    while (que_front != que_back) {
        int size = abs(que_front - que_back);
 
        while (size--) {
            col tmp = que_pop();
 
            for (int i = 0; i < 4++i) {
                int xx = tmp.x + dir[i][0];
                int yy = tmp.y + dir[i][1];
 
                if (xx < 0 || yy < 0 || xx >= r || yy >= c)
                    continue;
 
                if (xx == dst.x && yy == dst.y)
                    return cnt;
 
                if (map[xx][yy] == 0) {
                    que_push(xx, yy);
                    map[xx][yy] = -1;
                    continue;
                }
 
                if (map[xx][yy] == -1)
                    continue;
 
                if (map[xx][yy] <= cnt)
                    continue;
 
                que_push(xx, yy);
                map[xx][yy] = -1;
            }
        }
 
        cnt++;
    }
    return -1;
}
 
int main() {
    scanf("%d %d"&r, &c);
 
    for (int i = 0; i < r; ++i) {
        scanf("%s", buf);
        for (int j = 0; j < c; ++j) {
            if (buf[j] == '.'// 길
                continue;
            else if (buf[j] == 'D') { // 비버굴
                dst = { i,j };
                map[i][j] = -1;
            }
            else if (buf[j] == 'S') { // 고슴도치
                start = { i,j };
            }
            else if (buf[j] == 'X'// 돌
                map[i][j] = -1;
            else { // 물 
                waters[waters_cnt++= { i,j };
                map[i][j] = 1;
            }
        }
    }
 
    //물이 번지는 시간 기록
    for (int i = 0; i < waters_cnt; ++i)
        que_push(waters[i].x, waters[i].y);
    water_bfs();
 
 
    map[start.x][start.y] = -1;
    que_push(start.x, start.y);
    
    int ans = beaber_bfs();
    if (ans == -1)
        printf("KAKTUS");
    else
        printf("%d\n", ans - 1);
 
    return 0;
}
cs


'알고리즘 > 브루트 포스' 카테고리의 다른 글

백준) 1012 유기농 배추  (0) 2018.01.14
백준) 2206 벽 부수고 이동하기  (0) 2018.01.14
백준) 10216 Count Circle Groups  (0) 2017.10.09
백준) 2606 바이러스  (0) 2017.10.09
백준) 2178 미로 탐색  (3) 2017.10.09

+ Recent posts