[URL]
https://www.acmicpc.net/problem/16236
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다. 아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크
www.acmicpc.net
[풀이 과정]
* BFS + 시뮬
1. 아기 상어가 먹을 수 있는 물고기 개수를 구한다.
먹을 수 있는 물고기 개수 = 0 -> 종료
먹을 수 있는 물고기 개수 = 1 -> 그 위치(nearX, nearY)로 먹으러 간다
먹을 수 있는 물고기 개수 > 1 -> 가장 가까운 물고기 구한다. -> 그 위치(nearX, nearY)로 먹으러 간다
2. findNearFish()
현재 (baby.x, baby.y) 위치로 부터 이동 가능 하며, 조건 (거리 같을때 가장 위쪽, 같으면 가장 왼쪽)을 가지고
BFS탐색으로 가장 가까운 곳을 구한다. --> (nearX, nearY)
3. go()
목표 위치로 이동, map[][] 업데이트, 아기상어 현재 위치(baby.x, baby.y) 갱신, 아기상어 사이즈 갱신
[소스 코드]
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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | #include <stdio.h> #include <queue> #include <vector> #include <algorithm> using namespace std; struct BabyShark { int x; int y; int size; int sizeCheck; // 변하는 상어사이즈 관리 }; BabyShark baby; struct Fish { int x; int y; int dist; }; int N; int map[21][21]; int nearX = 0, nearY = 0, nearDist = 0; int dx[] = { 0, 0, -1, 1 }; int dy[] = { -1, 1, 0, 0 }; int resCnt = 0; // 물고기 정렬 (같은 거리면 가장 위쪽, 가장 위쪽에서도 여러마리면 가장 왼쪽) bool cmp(const Fish &a, const Fish &b) { if (a.x == b.x) return a.y < b.y; else return a.x < b.x; } // 초기화 & 입력 void init() { scanf("%d", &N); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { scanf("%d", &map[i][j]); if (map[i][j] == 9) { baby.x = i; baby.y = j; baby.size = 2; baby.sizeCheck = 2; map[i][j] = 0; } } } } // 먹을 수 있는 물고기 갯수 구하기(수정 필요) int findFish() { int fishCnt = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (map[i][j] != 0 && map[i][j] < baby.size) { fishCnt++; nearX = i; nearY = j; } } } return fishCnt; } // 현재 아기상어 위치로 부터 destX, destY까지 이동할 수 있는 거리 int BFS(int destX, int destY) { queue <pair<int, int>> q; bool visited[21][21] = { 0, }; int dist[21][21] = { 0, }; visited[baby.x][baby.y] = true; dist[baby.x][baby.y] = 0; q.push(make_pair(baby.x, baby.y)); while (!q.empty()) { int cx = q.front().first; int cy = q.front().second; q.pop(); for (int k = 0; k < 4; k++) { int nx = cx + dx[k]; int ny = cy + dy[k]; if (nx >= 0 && ny >= 0 && nx < N && ny < N) { if (map[nx][ny] <= baby.size && visited[nx][ny] == false) { visited[nx][ny] = true; dist[nx][ny] = dist[cx][cy] + 1; q.push(make_pair(nx, ny)); } } } } return dist[destX][destY]; } // 가장 가까운 물고기 찾자 void findNearFish() { vector <Fish> v; int Min = 987654; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (map[i][j] != 0 && map[i][j] < baby.size) { int tempDist = BFS(i, j); if (Min >= tempDist && tempDist > 0) { Min = tempDist; } } } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (map[i][j] != 0 && map[i][j] < baby.size) { if (BFS(i, j) == Min) { Fish temp; temp.x = i; temp.y = j; temp.dist = Min; v.push_back(temp); } } } } if (v.size() != 0) { sort(v.begin(), v.end(), cmp); nearX = v.front().x; nearY = v.front().y; nearDist = v.front().dist; } else { nearDist = 0; } v.clear(); } void go(int destX, int destY, int nearDist) // 목적지 x, y로 이동하여 물고기 먹음! { resCnt += nearDist; baby.x = destX; baby.y = destY; map[destX][destY] = 0; baby.sizeCheck--; if (baby.sizeCheck == 0) { baby.size++; baby.sizeCheck = baby.size; } } int main() { init(); while (true) { int fishCnt = findFish(); // 1.없는 경우 if (fishCnt == 0) break; // 2.한 마리인 경우 if (fishCnt == 1) { nearDist = BFS(nearX, nearY); if (nearDist == 0) break; else go(nearX, nearY, nearDist); // 먹으로 출발 } // 3.여러 마리인 경우 if (fishCnt > 1) { findNearFish(); // 찾자 가장 가까운 물고기 if (nearDist == 0) break; else go(nearX, nearY, nearDist); // 먹으로 출발 } } printf("%d\n", resCnt); return 0; } | cs |
'Algorithm > 백준' 카테고리의 다른 글
[BOJ] - 17143. 낚시왕 (0) | 2019.07.31 |
---|---|
17140. - 이차원 배열과 연산 (0) | 2019.07.16 |
[BOJ] - 13023. ABCDE (0) | 2019.07.10 |
[BOJ] - 14502. 연구소 (0) | 2019.07.03 |
[BOJ] - 2156. 포도주 시식 (0) | 2019.07.01 |