ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [18405] 경쟁적 전염
    BOJ 2021. 11. 6. 10:32

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

     

    18405번: 경쟁적 전염

    첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치

    www.acmicpc.net

    <문제>

    bfs를 여러번 돌려주는 시뮬레이션을 진행할 수도 있지만,

    거꾸로 생각하여 (X, Y)에서 최단거리->최소번호순서로 탐색을 진행해줄 수 있다.

    현재 거리가 S이상일때에는 가지치기로 잘라주고, 도중에 바이러스를 만났어도 바로 리턴하지 않고

    거리가 동일하면서 번호가 더 낮은 바이러스가 있는지를 탐색해준다.

    거리 S이상인 바이러스를 만나지 못했다면, 반대로 바이러스가 시작점으로 오기 위해

    S턴보다 더 많은 시간을 요하니 0을 리턴해줄 수 있다. 

     

    <소스코드>

    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
    #include <bits/stdc++.h>
    using namespace std;
    int n, k, S, X, Y, a[201][201], dy[4= {010-1}, dx[4= {10-10};
    bool visited[201][201];
    typedef struct {
        int y, x, turn;
    } state;
    int f(int sy, int sx) {
        queue<state> q;
        q.push({sy, sx, 0});
        visited[sy][sx] = true;
        int ans = 1e9;
        int minTurn = 0;
        bool flag = false;
        while (!q.empty()) {
            state cur = q.front();
            q.pop();
            if (cur.turn >= S) continue;
            if (flag && cur.turn > minTurn) continue;
            for (int i = 0; i < 4; i++) {
                int y = cur.y + dy[i];
                int x = cur.x + dx[i];
                if (y < 0 || x < 0 || y >= n || x >= n) continue;
                if (flag && a[y][x] > 0) ans = min(a[y][x], ans);
                if (a[y][x] > 0 && flag == false) {
                    flag = true;
                    ans = a[y][x];
                    minTurn = cur.turn;
                }
                if (a[y][x] == 0 && visited[y][x] == false) {
                    q.push({y, x, cur.turn + 1});
                    visited[y][x] = true;
                }
            }
        }
        if (ans == 1e9) ans = 0;
        return ans;
    }
    int main(void) {
        cin >> n >> k;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++cin >> a[i][j];
        cin >> S >> X >> Y;
        cout << f(X - 1, Y - 1);
        return 0;
    }
     
    cs

     

    'BOJ' 카테고리의 다른 글

    [2194] 유닛 이동시키기  (0) 2021.11.08
    [4781] 사탕 가게  (0) 2021.11.07
    [10835] 카드게임  (0) 2021.11.06
    [2234] 성곽  (0) 2021.11.05
    [15686] 치킨 배달  (0) 2021.11.05

    댓글