Study hard
(c++)백준 16236번: 아기 상어 본문
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가��
www.acmicpc.net
[풀이]
bfs 최단거리를 구하는 문제였다.
1. 아기 상어의 크기보다 작은 물고기를 벡터에 저장
2. 먹을 수 있는 물고기 없으면 종료
3. 1마리면 그 자리까지 갈 수 있는지 확인 후 갈 수 있으면 먹는다. 갈 수 없으면 종료. (Time += 물고기 먹으러 간 거리)
4. 2마리 이상이면 그 자리까지 갈 수 있는지와 어느 물고기가 가장 가까운지 비교해가며 거리를 구한다. 어떤 물고기로도 갈 수 없으면 종료. (Time += 가장 가까운 물고기 먹으러 간 거리)
※ 이동하다가 다른 먹을 수 있는 물고기를 만났을 때 큐에 추가하지 않으면 시간 단축 가능!
#include <iostream>
#include <queue>
#include <cstring>//memset
using namespace std;
struct Pos {
int x, y;
int d;//거리
};
struct Fish {
int x, y;
};
int N;
int Map[20][20];
bool visited[20][20];
vector<Fish>fish;//먹을 수 있는 물고기
const int dx[] = { -1,1,0,0 };//위,아래
const int dy[] = { 0,0,-1,1 };//왼,오
int sharkSize = 2;
int feedCnt = 0;
int fish_cnt;//먹을 수 있는 물고기 수
int sx, sy;//상어좌표
int Time = 0;
void checkFish() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (Map[i][j] != 0 && Map[i][j] < sharkSize)
fish.push_back({ i,j });
}
}
}
int getDist(int destx, int desty) {
memset(visited, false, sizeof(visited));
queue<Pos>q;
q.push({ sx,sy,0 });
visited[sx][sy] = true;
while (!q.empty()) {
int x = q.front().x;
int y = q.front().y;
int d = q.front().d;
q.pop();
if (x == destx && y == desty) {
return d;
}
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 (Map[nx][ny] > sharkSize)
continue;
//먹을 수 있는 다른 물고기 지나가는 경우 제외하면 시간 단축!
if ((nx != destx && ny != desty) && Map[nx][ny] > 0 && Map[nx][ny] < sharkSize)
continue;
if (visited[nx][ny] == false) {
visited[nx][ny] = true;
q.push({ nx,ny,d+1 });
}
}
}
return -1;
}
void solution() {
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) {
Map[i][j] = 0;
sx = i;
sy = j;
}
}
}
while (1) {
//먹을 수 있는 물고기 확인
checkFish();
fish_cnt = fish.size();
//cout << fish_cnt << '\n';
if (fish_cnt == 0)
break;
//물고기 한 마리면
if (fish_cnt == 1) {
int dist = getDist(fish[0].x, fish[0].y);
//물고기를 먹을 수 없으면
if (dist == -1)
break;
Time += dist;
sx = fish[0].x;
sy = fish[0].y;
Map[sx][sy] = 0;
feedCnt++;
}
else if(fish_cnt >= 2) {
int Min = 987654321;
int fx;
int fy;
bool flag = false;
for (int i = 0; i < fish_cnt; i++) {
int dist = getDist(fish[i].x, fish[i].y);
//물고기를 먹을 수 없으면
if (dist == -1)
continue;
if (dist < Min) {
flag = true;
Min = dist;
fx = fish[i].x;
fy = fish[i].y;
}
else if (dist == Min) {
if (fx == fish[i].x) {
if (fish[i].y < fy)
fy = fish[i].y;
}
else if (fish[i].x < fx) {
fx = fish[i].x;
fy = fish[i].y;
}
}
}
//아무 물고기도 먹을 수 없으면
if (flag == false)
break;
sx = fx;
sy = fy;
Map[sx][sy] = 0;
Time += Min;
feedCnt++;
}
if (sharkSize == feedCnt) {
sharkSize++;
feedCnt = 0;
}
fish.clear();
}
cout << Time << '\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
solution();
return 0;
}
'백준 > bfs, dfs' 카테고리의 다른 글
(c++)백준 1600번: 말이 되고픈 원숭이 (0) | 2021.02.12 |
---|---|
(c++)백준 16946번: 벽 부수고 이동하기 4 (0) | 2021.02.07 |
(c++)백준 17142번: 연구소 3 (0) | 2020.10.17 |
(c++)백준 14889번: 스타트와 링크 (0) | 2020.10.17 |
(c++)백준 15684번: 사다리 조작 (0) | 2020.10.16 |