기본적인 시뮬레이션 문제로 어렵지 않게 풀 수 있는 문제였습니다.
문제에서 주어진 조건을 차근차근 살펴봅시다.
cost
를 다익스트라 알고리즘으로 빠르게 구합니다.cost
가 가장 낮은 후보로 이동해서 먹이를 먹습니다.// https://www.acmicpc.net/problem/16236
#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
#include <algorithm>
using namespace std;
using t = tuple<int, int, int>;
static int N, ocean[20][20], dist[20][20], eatCount, sharkSize = 2;
static pair<int, int> curSharkPos, preyPos;
static constexpr int moving[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
bool dijkstra() {
// dist 배열 초기화, 시작 위치는 거리가 0이다.
fill(&dist[0][0], &dist[N - 1][N], 1e9);
dist[curSharkPos.first][curSharkPos.second] = 0;
// Min heap 초기화, 시작 위치 정보(y, x, cost)를 넣는다.
priority_queue<t, vector<t>, greater<t>> pq;
pq.push({curSharkPos.first, curSharkPos.second, 0});
vector<t> prey;
while(!pq.empty()) {
int y, x, cost; tie(y, x, cost) = pq.top();
pq.pop();
if (dist[y][x] < cost) continue;
for (int i = 0; i < 4; ++i) {
int ny = y + moving[i][0], nx = x + moving[i][1];
if (ny < 0 || ny >= N || nx < 0 || nx >= N || ocean[ny][nx] > sharkSize) continue;
int newCost = cost + 1;
if (dist[ny][nx] > newCost) {
dist[ny][nx] = newCost;
pq.push({ny, nx, newCost});
// 먹잇감 후보를 찾았다면 배열에 넣는다.
if (ocean[ny][nx] != 0 && ocean[ny][nx] < sharkSize) prey.push_back({newCost, ny, nx});
}
}
}
if (!prey.empty()) {
sort(begin(prey), end(prey)); // 먹잇감을 cost - y - x 순으로 오름차순 정렬한다.
preyPos = {get<1>(prey.front()), get<2>(prey.front())}; // 다음 먹잇감을 고르고 반환한다.
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> N;
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x) {
cin >> ocean[y][x];
if (ocean[y][x] == 9) { // 상어의 위치 파악 시 기록한다.
curSharkPos = {y, x};
ocean[y][x] = 0; // 그리고 상어가 있는 칸은 빈칸으로 바꾼다.
}
}
int answer = 0;
while (dijkstra()) {// 다익스트라 결과, 먹잇감을 찾았다면 while 반복문 진행.
// 먹잇감까지 최단경로를 answer에 더해주고 카운트 결과에 따라 상어 크기 증가.
answer += dist[preyPos.first][preyPos.second];
if (++eatCount == sharkSize) {
sharkSize++;
eatCount = 0;
}
ocean[preyPos.first][preyPos.second] = 0; // 먹힌 먹잇감은 사라지므로 0으로 표시해준다.
curSharkPos = preyPos; // 현재 상어의 위치를 갱신해준다.
}
cout << answer << '\n';
}