탈출
물이 인접한 칸으로 계속 불어날 때, 고슴도치가 물에 닿지 않고 목표지점까지 갈 수 있는지,
간다면 최단거리는 몇인지 알아내야 한다.
그래프 탐색문제이며, 최단거리를 알아내야 하므로 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 |