본문 바로가기
백준

백준 3197 백조의 호수

by 콩순이냉장고 2021. 12. 11.

문제 URL : https://www.acmicpc.net/problem/3197

 

3197번: 백조의 호수

입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500. 다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.

www.acmicpc.net

문제 접근법 :  사이즈가 매우큽니다. 1500*1500 이기때문에

두백조를 기준으로 큐를잡아서 매번 bfs를도려 매일 마다 한칸씩 얼음을 녹이는건 너무 비효율적입니다.

최대한 연산을 줄이는 방법을 선택해야하는데

 

백조가 갈수있는 방향까지 움직입니다. 얼음을 만나면 

어차피 얼음은 녹지만 가장 바깥지점부터 녹습니다. 그렇다면 물을 기준으로 잡고 좌우 상하방향으로 움직여서 얼음을 만나게되면 백조가 다움직인후 얼음을 녹이면서 탐색을진행하면 됩니다.

 

소스코드 : 

 

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
#include<bits/stdc++.h>
using namespace std;
char board[1500][1500];
int dy[4= { -1,0,1,0 };
int dx[4= { 0,1,0,-1 };
bool check[1500][1500];
vector<pair<intint>> v;
int n, m;
queue<pair<intint>> water;
void input() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> board[i][j];
            if (board[i][j] == 'L') {
                v.push_back({ i,j });
                board[i][j] = '.';
                water.push({ i,j });
            }
            else if (board[i][j] == '.') {
                water.push({ i,j });
            }
        }
    }
}
 
bool isrange(int y, int x) {
    return 0 <= y && y < n && 0 <= x && x < m;
}
 
int bfs() {
    queue<pair<intint>> q;
    int cnt = 0;
    q.push(v[0]);
    check[v[0].first][v[0].second] = 1;
    while (true) {
        bool flag = false;
        queue<pair<intint>> nq;
        while (!q.empty()) {
            int y, x;
            tie(y, x) = q.front();
            q.pop();
            if (y == v[1].first && x == v[1].second)
                return cnt;
 
            for (int i = 0; i < 4; i++) {
                int ny = y + dy[i];
                int nx = x + dx[i];
                if (isrange(ny, nx)&&check[ny][nx]==0) {
                    check[ny][nx] = true;
                    if (board[ny][nx] == '.') {
                        q.push({ ny,nx });
                    }
                    else if (board[ny][nx] == 'X')
                        nq.push({ ny,nx });
                    
                }
            }
        }
        int watersize = water.size();
        while (watersize--) {
            int y, x;
            tie(y, x) = water.front();
            water.pop();
            for (int i = 0; i < 4; i++) {
                int ny = y + dy[i];
                int nx = x + dx[i];
                if (isrange(ny, nx) && board[ny][nx] == 'X') {
                    board[ny][nx] = '.';
                    water.push({ ny,nx });
                }
            }
        }
        q = nq;
        cnt++;
    }
    return cnt;
}
void solve() {
    cout << bfs() << "\n";
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    input();
    solve();
}
 
cs

궁금한점 혹은 모르는점 어떤 질문이든 댓글은 언제나 환영입니다.

 

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

백준 18808 스티커 붙이기  (0) 2021.12.15
백준 11967 불켜기  (0) 2021.12.15
백준 1726 로봇  (0) 2021.12.11
백준 2933 미네랄  (0) 2021.11.29
백준 1244 스위치 켜고 끄기  (0) 2021.11.25