[BOJ][サムスン基出]16236小さなサメ
30037 ワード
質問へのアクセス
まずすべての魚の距離を-1にします。 到達可能な魚の距離をbfsで更新します。 もし、update後のすべての魚とサメの距離が-1であれば、-1に戻ります。魚が食べられないからです。(魚が食べられるかどうかを探る) 1匹以上の距離が-1でない場合は、最も距離の小さい魚を食べます。 複数の魚が最短距離にある場合、vectorで最初に探索された魚は、問題で定義された優先度に合致する。(入力時にvectorを順番に入れます。入力は左上からです。)
しかし、問題を解くとき、私が作った論理は整理されました.
次回はコメントしておけばよかったです.
に答える
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
typedef struct food {
int x;
int y;
int size;
int d;
bool life;
} food;
int N, M, rst, cnt, sx, sy, s_size;
int map[20][20];
vector <food> F;
int dx[] = { 0, 1, 0, -1 };
int dy[] = { 1, 0, -1, 0 };
void input() {
cin >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> map[i][j];
if (map[i][j] > 0 && map[i][j] < 9) {
food f;
f.x = i; f.y = j; f.size = map[i][j]; f.d = 0; f.life = true;
F.push_back(f);
}
else if (map[i][j] == 9) {
sx = i; sy = j; s_size = 2;
}
}
}
rst = 0; cnt = 0;
}
void get_target(int ret) {
rst += F[ret].d;
map[sx][sy] = 0;
sx = F[ret].x;
sy = F[ret].y;
F[ret].life = false;
map[F[ret].x][F[ret].y] = 9;
cnt++;
if (s_size == cnt) {
s_size++;
cnt = 0;
}
}
int is_range(int x, int y) {
if (x >= 0 && x < N && y >= 0 && y < N) return true;
return false;
}
int find_target() {
int is_visit[20][20];
memset(is_visit, 0, sizeof(is_visit));
queue <pair<pair<int, int>, int>> Q;
Q.push(make_pair(make_pair(sx, sy), 0));
is_visit[sx][sy] = 1;
for (int i = 0; i < F.size(); i++) {
F[i].d = -1;
}
// 1. 모든 먹을 수 있는 물고기에 대해 상어와의 거리를 구한다.
while (!Q.empty()) {
int cx = Q.front().first.first;
int cy = Q.front().first.second;
int d = Q.front().second;
Q.pop();
// 현재 위치에 물고기가 있는지 확인
for (int i = 0; i < F.size(); i++) {
if (map[cx][cy] && cx == F[i].x && cy == F[i].y) {
if (map[cx][cy] < s_size) {
F[i].d = d;
break;
}
}
}
for (int i = 0; i < 4; i++) {
int nx = cx + dx[i];
int ny = cy + dy[i];
if (!is_visit[nx][ny] && is_range(nx, ny) && map[nx][ny] <= s_size) {
is_visit[nx][ny] = 1;
Q.push(make_pair(make_pair(nx, ny), d + 1));
}
}
}
// 2. 살아 있는 물고기 중 먹을 수 있는 물고기가 한 마리 이상 있는가?
bool flag = false;
for (int i = 0; i < F.size(); i++) {
if (F[i].life && F[i].d != -1) flag = true;
}
if (!flag) return -1; // 없다면 종료
//있다면 min distance를 구하고 min distance에 해당하는 물고기 중 가장 왼쪽에 위치한 물고기
int m = 100000;
for (int i = 0; i < F.size(); i++) {
if (F[i].life && F[i].d != -1) m = min(m, F[i].d);
}
for (int i = 0; i < F.size(); i++) {
if (F[i].life && F[i].d != -1) {
if (F[i].d == m) return i;
}
}
}
void solve() {
while(true) {
int ret = find_target();
if (ret == -1) {
break;
}
get_target(ret);
}
}
int main() {
input();
solve();
cout << rst << endl;
}
Reference
この問題について([BOJ][サムスン基出]16236小さなサメ), 我々は、より多くの情報をここで見つけました https://velog.io/@kyoung99u/BOJ-16236-아기-상어テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol