https://www.acmicpc.net/problem/2468
2468번: 안전 영역
재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는
www.acmicpc.net
q.pop()을 빼먹어서 queue 길이가 자꾸만 증가하는 이유를 찾으려 디버깅을 계속했다... ㅠㅠ
76%에서 틀렸었는데, 아무 칸도 물에 잠기지 않을 수 있다는 조건을 빼먹었기 때문이다.
유사 문제
떨어진 영역(뭉탱이)의 개수를 구하는 방법을 모르겠다면 아래 문제와 해답을 참고하면 도움될 것이다.
2021.09.26 - [PS/백준] - 백준 4963번 (C++) 섬의 개수
백준 4963번 (C++) 섬의 개수
구글링 해서 풀었다면? 그래프 이론을 공부한 뒤에도 이 문제의 해답이 떠오르지 않는다면, 이 문제의 풀이를 암기하고, 비슷한 응용 문제를 풀어보는 게 효율적인 학습법일 것 같다. https://www.ac
synodic.tistory.com
풀이
주어진 입력을 받은 후,
물에 잠긴 영역을 rain이라는 이차원 배열에 체크했다.
(잠겼다면 1, 잠기지 않았다면 0)
bfs는 너비 우선 탐색으로,
이차원 배열의 그래프를 탐색할 때는 보통 dx, dy 등 배열을 사용하여 인접 영역을 방문 체크하며 탐색한다.
각 칸마다 bfs로 방문하고, 인접 칸을 visited == true로 체크한다.
그 칸에 인접하지 않은 영역과, 물에 잠기지 않은 영역은 방문되지 않을 것이다.
그렇다면 하나의 칸을 bfs로 방문했을 때,
bfs함수가 종료됨과 동시에 그 칸에 인접한 칸들은 전부 방문체크가 되어있다.
따라서 rain이라는 이차원 배열에 iteration을 진행하며
칸이 물에 잠겨있지 않고, 이미 방문한 곳도 아니라면 cnt++한다.
최대 높이가 100이므로 0에서 100까지 높이를 증감하며 max함수로 최대 cnt값을 찾고 그것을 출력한다.
코드
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int MAX = 100;
int N,M,K;
int arr[MAX][MAX];
int rain[MAX][MAX]; // 물에 잠긴 후 시뮬레이션을 위한 배열
bool visited[MAX][MAX] = {false, };
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
void bfs(int a, int b) {
queue<pair<int, int>> q;
q.push({a, b});
visited[a][b] = true;
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int it = 0; it < 4; it++) {
int nx = x + dx[it];
int ny = y + dy[it];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) {
continue;
}
if (visited[nx][ny] || rain[nx][ny]) {
continue;
}
visited[nx][ny] = true;
q.push({nx, ny});
}
}
return;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int cnt = 0, ans = 0;
cin >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> arr[i][j];
rain[i][j] = 0;
}
}
for (int k = 0; k <= 100; k++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (arr[i][j] <= k) {
rain[i][j] = 1; // 물에 잠기면 1
}
}
} // 이제 rain에 잠긴 곳만 표시되어 있음
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!rain[i][j] && !visited[i][j]) { // 잠긴 곳이 아니라면 탐색
cnt++;
bfs(i, j);
}
}
}
ans = max(ans, cnt);
// 초기화
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
rain[i][j] = 0;
visited[i][j] = false;
cnt = 0;
}
}
}
cout << ans;
return 0;
}
'PS > BOJ' 카테고리의 다른 글
왜 안풀림 (4) | 2022.08.15 |
---|---|
백준 1913번 (C++) 달팽이 (0) | 2022.08.11 |
백준 14442 (C++) 벽 부수고 이동하기 2 (2) | 2022.03.18 |
백준 2644 (C++) 촌수계산 (2) | 2022.03.12 |
백준 23559 (C++) 밥 (0) | 2022.02.08 |