ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BOJ 18128, C++] 치삼이의 징검다리 건너기
    알고리즘/BOJ 2021. 10. 1. 18:28
    반응형

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

     

    18128번: 치삼이의 징검다리 건너기

    첫 번째 줄에 땅의 크기 N(3 ≤ N ≤ 1,000), 물 생성지 개수 W(1 ≤ W ≤ N)가 주어진다. 두 번째 줄부터 W+1줄까지 물의 생성 위치 x(행), y(열) (1 ≤ x, y ≤ N)가 주어진다. W+2줄부터 N개의 줄에

    www.acmicpc.net

     

     

    풀이

    물 이동은 1초에 상하좌우 한 번씩 움직이므로 BFS로 만들 수 있습니다.

    치삼이는 상하좌우와 대각선을 포함한 8개의 방향으로 움직일 수 있는데, 치삼이가 이동하는데 시간이 걸리지 않는다고 했으므로 치삼이가 도착할 수 있는 시간은 치삼이의 이동 경로중에 제일 늦게 식은 돌의 시간이 됩니다.

    그래서 치삼이의 시간을 구하는 것은 다익스트라 알고리즘을 통해 구할 수 있게 됩니다.

     

    주의할 점은 시작점과 도착점의 돌이 물에 닿지 않아도 된다는 것 입니다. 그래서 다익스트라를 시작할 때 출발돌이 식은 시간을 무시하고 돌리고, 도착할 때는 도착돌보다 도착점 주변의 돌중에 빨리 식은 돌이 있는지 찾아보면 됩니다.

     

     

     

    코드

    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
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <string>
    using namespace std;
    using ll = long long;
     
    const int N = 1001;
    int n, w, x, y, S[N][N], visited[N][N], MAP[N][N];
    int dx[4= { 1-100 }, dy[4= { 001-1 };
    int cx[8= { -1-1-100111 }, cy[8= { -101-11-101 };
    char k;
     
     
     
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        memset(MAP, -1sizeof(MAP));
        memset(visited, -1sizeof(visited));
        memset(S, -1sizeof(S));
     
        queue<pair<intint>> q;
        priority_queue<pair<intpair<intint>>> pq;
     
        cin >> n >> w;
        for (int i = 0; i < w; i++) {
            cin >> x >> y;
            q.push(make_pair(--x, --y));
            S[x][y] = 0;
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> k;
                MAP[i][j] = k - '0';
            }
     
        }
     
        while (!q.empty()) {
            pair<intint> p = q.front(); q.pop();
            int x = p.first, y = p.second;
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i], ny = y + dy[i];
                if (0 <= nx && nx < n && 0 <= ny && ny < n && S[nx][ny] == -1) {
                    S[nx][ny] = S[x][y] + 1;
                    q.push(make_pair(nx, ny));
                }
            }
        }
     
        pq.push(make_pair(0make_pair(00)));
        while (!pq.empty()) {
            pair<intpair<intint>> p = pq.top(); pq.pop();
            int t = p.first, x = p.second.first, y = p.second.second;
            if (x == n - 1 && y == n - 1) {
                if (visited[x - 1][y] != -1) t = -min(-t, visited[x - 1][y]);
                if (visited[x][y - 1!= -1) t = -min(-t, visited[x][y - 1]);
                if (visited[x - 1][y - 1!= -1) t = -min(-t, visited[x - 1][y - 1]);
                cout << -<< endl;
                return 0;
            }
            for (int i = 0; i < 8; i++) {
                int nx = x + cx[i], ny = y + cy[i];
                if (0 <= nx && nx < n && 0 <= ny && ny < n && MAP[nx][ny] == 1 && visited[nx][ny] == -1) {
                    visited[nx][ny] = max(S[nx][ny], -t);
                    pq.push(make_pair(-visited[nx][ny], make_pair(nx, ny)));
                }
            }
        }
     
        cout << -1;
    }
    cs
    반응형

    댓글

Designed by Tistory.