본문 바로가기
백준

[백준 16236] 아기 상어, C++

by 황인태(intaehwang) 2020. 1. 31.
반응형

https://www.acmicpc.net/problem/16236

 

16236번: 아기 상어

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다. 아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크

www.acmicpc.net

 본 문제는 삼성 SW 역량 테스트 기출 문제로 크기가 2인 아기 상어가 1초에 상하좌우로 인접한 한 칸씩 이동하면서 물고기를 먹는 문제다. 아기 상어는 자신의 크기보다 작은 물고기만 먹을 수 있고, 크기가 같은 물고기는 지나갈 수 있다. 이동결정 방법에 조건이 있는데

  1. 더 이상 먹을 수 있는 물고기가 없다면 끝.
  2. 먹을 수 있는 물고기가 1마리면, 그 물고기를 먹는다.
  3. 먹을 수 있는 물고기가 1마리보다 많으면, 거리가 가장 가까운 물고기를 먹는다.
    1. 거리는 지나야하는 칸의 개수의 최소값이다.
    2. 거리가 가까운 물고기가 많다면, (1) 가장 위에 있는 물고기 (2) 가장 왼쪽에 있는 물고기

의 조건이 있다.

해결 방법은

  1. 현재 아기상어의 위치에서 먹을 수 있는 물고기 탐색
  2. 물고기들 거리, 위, 왼쪽 순으로 정렬
  3. 먹으러 간다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <cstdio>
#include <queue>
#include <tuple>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
bool cmp(tuple<intintint> v, tuple<intintint> u) {
    int vx, vy, vcnt;
    int ux, uy, ucnt;
    tie(vx, vy, vcnt) = v;
    tie(ux, uy, ucnt) = u;
    if (vcnt == ucnt) {
        if (vx == ux) {
            // 가장 위에
            return vy < uy;
        }
        // 가장 왼쪽
        else return vx < ux;
    }
    // 거리 순
    else return vcnt < ucnt;
}
 
int d[22][22];
int dx[] = {1-100};
int dy[] = {001-1};
int n, sx, sy;
int shark = 2, eat = 0, ans = 0;
bool chk[22][22];
 
int main() {
    scanf("%d"&n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d"&d[i][j]);
            if (d[i][j] == 9) {
                sx = i;
                sy = j;
                d[i][j] = 0;
            }
        }
    }
    queue<tuple<intintint>> q;
    q.push(make_tuple(sx, sy, 0));
    chk[sx][sy] = true;
    
    vector<tuple<intintint>> v;
    while (true) {
        while (!q.empty()) {
            int x, y, cnt;
            tie(x, y, cnt) = q.front();
            q.pop();
            for (int k = 0; k < 4; k++) {
                int nx = x + dx[k];
                int ny = y + dy[k];
                if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
                    if (!chk[nx][ny]) {
                        if (d[nx][ny] > shark) continue;
                        // 먹을 수 있는 물고기 탐색
                        else if (d[nx][ny] != 0 && d[nx][ny] < shark){
                            chk[nx][ny] = true;
                            q.push(make_tuple(nx, ny, cnt+1));
                            v.push_back(make_tuple(nx, ny, cnt+1));
                        }
                        else {
                            chk[nx][ny] = true;
                            q.push(make_tuple(nx, ny, cnt+1));
                        }
                    }
                }
            }
        }
        // 더 이상 먹을 수 잇는 물고기가 없을 때
        if (v.size() == 0) {
            printf("%d\n", ans);
            return 0;
        }
        // 먹을 수 있는 물고기 정렬
        sort(v.begin(), v.end(), cmp);
        int a, b, c;
        tie(a, b, c) = v.front();
        eat += 1;
        ans += c;
        d[a][b] = 0;
        memset(chk, falsesizeof(chk));
        chk[a][b] = true;
        q.push(make_tuple(a, b, 0));
        v.clear();
        if (eat == shark) {
            shark += 1;
            eat = 0;
        }
    }
}
cs
반응형

'백준' 카테고리의 다른 글

[백준 17088] 등차수열 변환, C++  (0) 2020.02.02
[백준 16932] 모양 만들기, C++  (0) 2020.01.31
[백준 15686] 치킨 배달, C++  (0) 2020.01.31
[백준 1932] 정수 삼각형, C++  (0) 2020.01.15
[백준 2156] 포도주 시식, C++  (0) 2020.01.14
Buy me a coffeeBuy me a coffee

댓글