N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다.
아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다.
아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크기보다 작은 물고기만 먹을 수 있다. 따라서, 크기가 같은 물고기는 먹을 수 없지만, 그 물고기가 있는 칸은 지나갈 수 있다.
아기 상어가 어디로 이동할지 결정하는 방법은 아래와 같다.
아기 상어의 이동은 1초 걸리고, 물고기를 먹는데 걸리는 시간은 없다고 가정한다. 즉, 아기 상어가 먹을 수 있는 물고기가 있는 칸으로 이동했다면, 이동과 동시에 물고기를 먹는다. 물고기를 먹으면, 그 칸은 빈 칸이 된다.
아기 상어는 자신의 크기와 같은 수의 물고기를 먹을 때 마다 크기가 1 증가한다. 예를 들어, 크기가 2인 아기 상어는 물고기를 2마리 먹으면 크기가 3이 된다.
공간의 상태가 주어졌을 때, 아기 상어가 몇 초 동안 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는지 구하는 프로그램을 작성하시오.
첫째 줄에 공간의 크기 N(2 ≤ N ≤ 20)이 주어진다.
둘째 줄부터 N개의 줄에 공간의 상태가 주어진다. 공간의 상태는 0, 1, 2, 3, 4, 5, 6, 9로 이루어져 있고, 아래와 같은 의미를 가진다.
아기 상어는 공간에 한 마리 있다.
첫째 줄에 아기 상어가 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는 시간을 출력한다.
class Shark {
public:
int size;
int x;
int y;
int distance;
Shark(int size, int x, int y, int distance);
};
Shark::Shark(int size, int x, int y, int distance = INF) {
this->size = size;
this->x = x;
this->y = y;
this->distance = distance;
}
distance
값을 갱신해준다.BFS
를 활용한다.INF
값으로 갱신한다.distance
, x
, y
순으로 정렬해준다.compare
함수를 만들어주었다.bool compare(Shark &a, Shark &b) {
if (a.distance == b.distance){
if (a.x == b.x) {
return a.y < b.y;
}
return a.x < b.x;
}
return a.distance < b.distance;
}
distance
값이 INF
일 경우 더 이상 이동을 할 수 없기 때문에 반복문을 종료한다.shark.distance
의 초기값과 갈 수 없을 경우 값을 -1로 설정했다가 INF
로 수정했다.distance
가 -1인 원소들이 가장 앞으로 정렬된다. if (sharkArr.size() == 0 || sharkArr[0].distance == INF) break;
babySharkX
와 babySharkY
변수를 이용해서 위치 정보를 이용하였다.#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define INF 987654321
using namespace std;
int n;
int map[20][20];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int babySharkX;
int babySharkY;
int babySharkSize = 2;
int babySharkEaten = 0;
class Shark {
public:
int size;
int x;
int y;
int distance;
Shark(int size, int x, int y, int distance);
};
Shark::Shark(int size, int x, int y, int distance = INF) {
this->size = size;
this->x = x;
this->y = y;
this->distance = distance;
}
vector<Shark> sharkArr;
int bfs(Shark &shark) {
int route[20][20] = {0, };
queue<pair<int, int> > q;
q.push(make_pair(babySharkX, babySharkY));
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
if (x == shark.x && y == shark.y) {
return route[x][y];
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
if (route[nx][ny] != 0) continue;
if (babySharkSize < map[nx][ny]) continue;
route[nx][ny] = route[x][y] + 1;
q.push(make_pair(nx, ny));
}
}
return INF;
}
bool compare(Shark &a, Shark &b) {
if (a.distance == b.distance){
if (a.x == b.x) {
return a.y < b.y;
}
return a.x < b.x;
}
return a.distance < b.distance;
}
int main() {
cin.tie(NULL);
ios_base::sync_with_stdio(false);
int answer = 0;
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> map[i][j];
if (map[i][j] == 9) {
babySharkX = i;
babySharkY = j;
map[i][j] = 0;
}
else if (0 < map[i][j]) {
sharkArr.push_back(Shark(map[i][j], i, j));
}
}
}
while (true) {
for (int i = 0; i < sharkArr.size(); i++) {
if (sharkArr[i].size < babySharkSize) {
sharkArr[i].distance = bfs(sharkArr[i]);
}
}
sort(sharkArr.begin(), sharkArr.end(), compare);
if (sharkArr.size() == 0 || sharkArr[0].distance == INF) break;
answer += sharkArr[0].distance;
map[sharkArr[0].x][sharkArr[0].y] = 0;
babySharkX = sharkArr[0].x;
babySharkY = sharkArr[0].y;
sharkArr.erase(sharkArr.begin());
babySharkEaten++;
if (babySharkEaten == babySharkSize) {
babySharkSize++;
babySharkEaten = 0;
}
}
cout << answer;
}