삼성 SW역량테스트 기출문제이다.
이 문제는 BFS+문제의 요구사항에 맞는 구현 능력이 있다면 해결할 수 있다.
처음엔 문제를 읽어도 '뭐 어떻게 하라는 거지' 생각에 문제 이해하는데 시간이 오래 걸렸다. 필자가 언어이해력이 떨어진 것이 문제일 수도 있겠지만 어째뜬, 2번째 테스트케이스를 손으로 그려가며 문제를 이해할 수 있었다.
이 문제는, 상어의 위치, 크기, 먹을 수 있는 물고기 이 3가지를 저장하는 자료구조를 이용하여 BFS탐색을 통해 진행한다.
BFS탐색을 하면서 먹을 수 있는 물고기의 위치로 모두 이동하고 그 수가 많다면 문제의 조건에 맞게끔 먼저 먹는다. 그 다음 상어의 위치를 갱신하고 그 위치에서 계속 BFS탐색을 진행한다. 먹을 수 있는 물고기가 없다면 종료한다.
#include<iostream>
#include<math.h>
#include<stack>
#include<string.h>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#include<iterator>
using namespace std;
struct info {
int a = 0, b = 0, size = 2, cnt = 0;
};
int n, arr[21][21],visit[21][21],chk,ans;
int dx[4] = { 1,-1,0,0 }, dy[4] = { 0,0,1,-1 };
info in;
void bfs(int a, int b) {
int dis = 0,k=0;
vector<pair<int, int>> v;
queue<info> q;
visit[a][b] = 1;
q.push(in);
while (!q.empty()) {
int sz = q.size();
if (sz == 0) break;
for (int ee = 0; ee < sz; ee++) {
int x, y, s, c;
x = q.front().a;
y = q.front().b;
s = q.front().size;
c = q.front().cnt;
q.pop();
for (int i = 0; i < 4; i++) {
int kx, ky;
kx = x + dx[i];
ky = y + dy[i];
if (kx < 0 || kx >= n || ky < 0 || ky >= n) continue;
if (visit[kx][ky] == 0 && arr[kx][ky] <= s) {
in.a = kx;
in.b = ky;
if (visit[kx][ky] == 0 && arr[kx][ky] != 0 && arr[kx][ky] < s) {
in.cnt = c;
v.push_back({ kx,ky });
if (arr[kx][ky] < s) chk = 1;
k++;
}
visit[kx][ky] = 1;
q.push(in);
}
}
}
dis++;
if (chk == 1) break;
}
in.cnt++;
if (in.size == in.cnt) {
in.size = in.size + 1;
in.cnt = 0;
}
if (!v.empty()) {
sort(v.begin(), v.end());
in.a = v[0].first;
in.b = v[0].second;
arr[in.a][in.b] = 0;
}
if (chk == 1) ans = ans + dis;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> arr[i][j];
if (arr[i][j] == 9) {
in.a = i;
in.b = j;
arr[i][j] = 0;
}
}
}
for (int i = 0; i < 1000; i++) {
bfs(in.a, in.b);
memset(visit, 0, sizeof(visit));
if (chk == 0) break;
chk = 0;
}
printf("%d", ans);
return 0;
}