Skip to content

Commit 4c67936

Browse files
committed
[Gold III] Title: 아기 상어, Time: 4 ms, Memory: 2028 KB -BaekjoonHub
1 parent 871b68e commit 4c67936

2 files changed

Lines changed: 180 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# [Gold III] 아기 상어 - 16236
2+
3+
[문제 링크](https://www.acmicpc.net/problem/16236)
4+
5+
### 성능 요약
6+
7+
메모리: 2028 KB, 시간: 4 ms
8+
9+
### 분류
10+
11+
구현, 그래프 이론, 그래프 탐색, 시뮬레이션, 너비 우선 탐색
12+
13+
### 제출 일자
14+
15+
2025년 8월 12일 21:11:11
16+
17+
### 문제 설명
18+
19+
<p>N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다.</p>
20+
21+
<p>아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다.</p>
22+
23+
<p>아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크기보다 작은 물고기만 먹을 수 있다. 따라서, 크기가 같은 물고기는 먹을 수 없지만, 그 물고기가 있는 칸은 지나갈 수 있다.</p>
24+
25+
<p>아기 상어가 어디로 이동할지 결정하는 방법은 아래와 같다.</p>
26+
27+
<ul>
28+
<li>더 이상 먹을 수 있는 물고기가 공간에 없다면 아기 상어는 엄마 상어에게 도움을 요청한다.</li>
29+
<li>먹을 수 있는 물고기가 1마리라면, 그 물고기를 먹으러 간다.</li>
30+
<li>먹을 수 있는 물고기가 1마리보다 많다면, 거리가 가장 가까운 물고기를 먹으러 간다.
31+
<ul>
32+
<li>거리는 아기 상어가 있는 칸에서 물고기가 있는 칸으로 이동할 때, 지나야하는 칸의 개수의 최솟값이다.</li>
33+
<li>거리가 가까운 물고기가 많다면, 가장 위에 있는 물고기, 그러한 물고기가 여러마리라면, 가장 왼쪽에 있는 물고기를 먹는다.</li>
34+
</ul>
35+
</li>
36+
</ul>
37+
38+
<p>아기 상어의 이동은 1초 걸리고, 물고기를 먹는데 걸리는 시간은 없다고 가정한다. 즉, 아기 상어가 먹을 수 있는 물고기가 있는 칸으로 이동했다면, 이동과 동시에 물고기를 먹는다. 물고기를 먹으면, 그 칸은 빈 칸이 된다.</p>
39+
40+
<p>아기 상어는 자신의 크기와 같은 수의 물고기를 먹을 때 마다 크기가 1 증가한다. 예를 들어, 크기가 2인 아기 상어는 물고기를 2마리 먹으면 크기가 3이 된다.</p>
41+
42+
<p>공간의 상태가 주어졌을 때, 아기 상어가 몇 초 동안 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는지 구하는 프로그램을 작성하시오.</p>
43+
44+
### 입력
45+
46+
<p>첫째 줄에 공간의 크기 N(2 ≤ N ≤ 20)이 주어진다.</p>
47+
48+
<p>둘째 줄부터 N개의 줄에 공간의 상태가 주어진다. 공간의 상태는 0, 1, 2, 3, 4, 5, 6, 9로 이루어져 있고, 아래와 같은 의미를 가진다.</p>
49+
50+
<ul>
51+
<li>0: 빈 칸</li>
52+
<li>1, 2, 3, 4, 5, 6: 칸에 있는 물고기의 크기</li>
53+
<li>9: 아기 상어의 위치</li>
54+
</ul>
55+
56+
<p>아기 상어는 공간에 한 마리 있다.</p>
57+
58+
### 출력
59+
60+
<p>첫째 줄에 아기 상어가 엄마 상어에게 도움을 요청하지 않고 물고기를 잡아먹을 수 있는 시간을 출력한다.</p>
61+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
#include <tuple>
5+
6+
#define MAX 21
7+
8+
using namespace std;
9+
10+
int N;
11+
int map[MAX][MAX]{};
12+
int sharkX, sharkY = 0;
13+
int sharkSize = 2;
14+
int eatenFish = 0;
15+
int dx[4] = {0, -1, 0, 1};
16+
int dy[4] = {1, 0, -1, 0};
17+
int visited[MAX][MAX]{};
18+
int shortPath[MAX][MAX]{};
19+
vector<tuple<int, int, int>> fishList;
20+
int answer = 0;
21+
22+
void input() {
23+
cin >> N;
24+
for (int i = 0; i < N; i++) {
25+
for (int j = 0; j < N; j++) {
26+
cin >> map[i][j];
27+
if (map[i][j] == 9) {
28+
sharkX = i;
29+
sharkY = j;
30+
map[i][j] = 0;
31+
}
32+
}
33+
}
34+
}
35+
36+
void bfs() {
37+
// 1) 초기화: visited, 최단거리 배열
38+
for (int i = 0; i < N; i++) {
39+
for (int j = 0; j < N; j++) {
40+
visited[i][j] = 0;
41+
shortPath[i][j] = 0;
42+
}
43+
}
44+
45+
// 2) BFS로 현재 상어 위치에서 모든 곳의 최단 경로 구하기
46+
queue<tuple<int, int, int>> q;
47+
q.push({sharkX, sharkY, 1});
48+
49+
while (!q.empty()) {
50+
int x = get<0>(q.front());
51+
int y = get<1>(q.front());
52+
int dist = get<2>(q.front());
53+
q.pop();
54+
55+
for (int i = 0; i < 4; i++) {
56+
int nx = x + dx[i];
57+
int ny = y + dy[i];
58+
59+
if (nx < 0 || nx >= N || ny < 0 || ny >= N || visited[nx][ny]) continue;
60+
if (map[nx][ny] <= sharkSize) { // 현재는 먹는 것보다는 이동해서 최단경로를 구하는 게 우선!!!
61+
shortPath[nx][ny] += dist;
62+
q.push({nx, ny, dist + 1});
63+
visited[nx][ny]++;
64+
}
65+
}
66+
}
67+
68+
// 3) 현재 상어가 잡을 수 있는 모든 물고기 구하기
69+
for (int i = 0; i < N; i++) {
70+
for (int j = 0; j < N; j++) {
71+
if (map[i][j] > 0 && map[i][j] < sharkSize && map[i][j] != 9 && shortPath[i][j]) {
72+
fishList.push_back({shortPath[i][j], i, j});
73+
}
74+
}
75+
}
76+
}
77+
78+
void update() {
79+
// 1) 원래 있던 상어 위치를 0으로 초기화
80+
map[sharkX][sharkY] = 0;
81+
82+
// 2) 오름차순 정렬 후, 정보 뽑아내기
83+
// 최단 거리, 죄표 오름차순 정렬 => 위쪽, 왼쪽 순서
84+
sort(fishList.begin(), fishList.end());
85+
int dist = get<0>(fishList.front());
86+
sharkX = get<1>(fishList.front());
87+
sharkY = get<2>(fishList.front());
88+
89+
// 3) 상어 위치 수정 및 업데이트
90+
map[sharkX][sharkY] = 9;
91+
answer += dist;
92+
eatenFish++;
93+
if (sharkSize == eatenFish) {
94+
sharkSize++;
95+
eatenFish = 0;
96+
}
97+
98+
fishList.clear();
99+
}
100+
101+
int main() {
102+
// Input
103+
input();
104+
105+
while (true) {
106+
int isCatch = 0;
107+
// BFS
108+
bfs();
109+
isCatch = fishList.size();
110+
if (isCatch) {
111+
// Update
112+
update();
113+
} else {
114+
// Exit
115+
cout << answer << '\n';
116+
return 0;
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)