알고리즘/백준

[백준 2573] 빙산 C++

겜도리도리 2021. 10. 31. 23:39
반응형

문제

백준 2573 빙산 C++

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을

www.acmicpc.net

풀이

일반적인 bfs 문제입니다.

1. melt() 함수로 주변에 바닷물 만큼 빙산의 크기를 감소시켜줍니다.

2. 빙산이 모두 0이 됐다면 0을 출력해줍니다.

3. 빙산이 있다면 (0이 아닌 숫자가 있다면) bfs를 통해 빙산의 개수를 세어줍니다.

4. 빙산의 개수가 2개 이상이라면, 걸린 시간 t를 출력합니다.

소스 코드

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
 
int dx[] = { 00-11 };
int dy[] = { -1100 };
int map[300][300];
int temp[300][300];
int N, M, cnt;
int t;
bool isAllZero = false;
bool visited[300][300];
 
// temp에서 인접한 0찾기
void melt() {
    isAllZero = true;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (map[i][j] == 0) {
                continue;
            }
            // 0이 아닐 경우 (빙산이 있을 경우)
            else {
                isAllZero = false;
            }
            // 주변 바닷물(0) 탐색
            int nearZero = 0;
            for (int k = 0; k < 4; k++) {
                int nx = j + dx[k];
                int ny = i + dy[k];
                if (nx >= 0 && ny >= 0 && nx < M && ny < N && map[ny][nx] == 0) {
                    nearZero++;
                }
                temp[i][j] = nearZero;
            }
        }
    }
    // 주변 바닷물 만큼 빙산 크기 감소
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            map[i][j] -= temp[i][j];
            if (map[i][j] < 0) {
                map[i][j] = 0;
            }
        }
    }
}
 
// bfs로 빙산개수 찾기
void bfs(int sx, int sy) {
    if (visited[sy][sx])
        return;
    visited[sy][sx] = true;
    if (map[sy][sx] == 0)
        return;
    queue<pair<intint>> q;
    q.push(make_pair(sx, sy));
    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && ny >= 0 && nx < M && ny < N) {
                if (!visited[ny][nx] && map[ny][nx] != 0) {
                    visited[ny][nx] = true;
                    q.push(make_pair(nx, ny));
                }
            }
        }
    }
    cnt++;
}
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
 
    // 입력
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> map[i][j];
        }
    }
 
    while (1)
    {
        t++;
        melt();
        // 빙산이 없으면 (모두 0이면) 0출력
        if (isAllZero) {
            cout << 0;
            break;
        }
        // 초기화
        memset(visited, 0sizeof(visited));
        cnt = 0;
        // bfs로 빙산 개수 세기
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                bfs(j, i);
            }
        }
        // 빙산이 2개 이상이면 출력
        if (cnt >= 2) {
            cout << t;
            break;
        }
    }
    return 0;
}
cs
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 17298] 오큰수 C++  (0) 2021.11.04
[백준 1967] 트리의 지름 C++  (0) 2021.11.02
[백준 1261] 알고스팟 C++  (0) 2021.10.30
[백준 17144] 미세먼지 안녕! C++  (0) 2021.10.29
[백준 1707] 이분 그래프 C++  (0) 2021.10.26