백준 문풀

백준 2468

조강학 2025. 1. 1. 16:35

안전 영역 


문제

재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는 안전한 영역이 최대로 몇 개가 만들어 지는 지를 조사하려고 한다. 이때, 문제를 간단하게 하기 위하여, 장마철에 내리는 비의 양에 따라 일정한 높이 이하의 모든 지점은 물에 잠긴다고 가정한다.

어떤 지역의 높이 정보는 행과 열의 크기가 각각 N인 2차원 배열 형태로 주어지며 배열의 각 원소는 해당 지점의 높이를 표시하는 자연수이다. 예를 들어, 다음은 N=5인 지역의 높이 정보이다.

 


입력

첫째 줄에는 어떤 지역을 나타내는 2차원 배열의 행과 열의 개수를 나타내는 수 N이 입력된다. N은 2 이상 100 이하의 정수이다. 둘째 줄부터 N개의 각 줄에는 2차원 배열의 첫 번째 행부터 N번째 행까지 순서대로 한 행씩 높이 정보가 입력된다. 각 줄에는 각 행의 첫 번째 열부터 N번째 열까지 N개의 높이 정보를 나타내는 자연수가 빈 칸을 사이에 두고 입력된다. 높이는 1이상 100 이하의 정수이다.

 


#include<iostream>
#include<vector>
#include<queue>
using namespace std;
vector<vector<int>>land;
vector<vector<bool>>safe;

int n,max_size=0,min_size=100;
int max_count = 0;

int find() {
	int safe_cnt = 0;
	vector<vector<bool>>visit(n,vector<bool>(n,0));
	int dx[] = {0,1,0,-1};
	int dy[] = { 1,0,-1,0 };
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (safe[i][j] == 1&&visit[i][j]==0) {
				safe_cnt++;
				visit[i][j] = 1;
				queue<pair<int, int>>q;
				q.push(make_pair(i, j));

				while (!q.empty()) {
					int x = q.front().first;
					int y = q.front().second;
					q.pop();
					for (int k = 0; k < 4; k++) {
						int new_x  =x+ dx[k];
						int new_y = y + dy[k];
						if (new_x >= 0 && new_y >= 0 && new_x < n && new_y < n) {
							if (safe[new_x][new_y] == 1 && visit[new_x][new_y] == 0) {
								q.push(make_pair(new_x, new_y));
								visit[new_x][new_y] = 1;
							}
						}
					}
				}

			}
		}
	}
	return safe_cnt;
}

void rain(int m) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (land[i][j] > m)
				safe[i][j] = 1;
			else
				safe[i][j] = 0;
		}
	}

}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n;
	land.resize(n, vector<int>(n, 0));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			int l;
			cin>>l;
			land[i][j] = l;
			if (l > max_size)
				max_size = l;
			if (l < min_size)
				min_size = l;
		}
	}
	int cnt = 1;
	
	safe.resize(n, vector<bool>(n, 0));
	for (int i = min_size-1; i < max_size ; i++) {
		rain(i);
		cnt=find();
		if (cnt > max_count)
			max_count = cnt;
	}

	cout << max_count;
	return 0;
}

 

 

입력받은 땅의 높이를 저장할 이차원 정수 벡터 land와 각 물의 높이만큼 안전 영역을 저장하는 이차원 부울 safe벡터 정의 

계산 수를 줄이기 위해 땅의 최고높이와 최저 높이를 저장하고 그 안에서 물 높이를 조절해가면서 최대 수를 찾는다. 

 

find 함수의 정의

전체 배열을 탐색하면서 bfs를 활용하였다. 

방문하지 않았고 안전한 영역이라면 bfs를 통해 해당 위치에서 접근 가능한 위치까지 방문 배열에 추가한다.  

전체 배열을 이중 for문으로 돌 때 이미 방문한 경우라면 카운트 하지 않으므로 우리가 찾고 있던 안전한 영역의 개수를 찾을 수 있다.

 

rain함수의 정의

물의 높이가 주어졌을 때 safe함수의 초기화를 해준다. 이중 for문과 if문을 통해 간단히 작성하였다.

 

 

 

 

 

 

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

백준 1987 알파벳  (0) 2025.01.13
백준 9084  (0) 2024.11.10
배낭 알고리즘  (0) 2024.11.09
백준 2656 전깃줄  (0) 2024.11.05
백준 1920 수 찾기  (0) 2024.09.30