Algorithm/DFS, BFS
백준 영역 구하기(2583) C++ 풀이
khjtoy
2023. 1. 20. 00:44
알고리즘 영역
그래프 이론
그래프 탐색
너비 우선 탐색
깊이 우선 탐색
문제 해결 아이디어
연결되어 있는 빈칸의 개수를 DFS를 통해 연결하여 개수를 세어 출력하면 된다.
코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int m, n, k;
int arr[101][101];
// 상하좌우 세팅
int dirX[] = { 0, 0, -1, 1 };
int dirY[] = { -1, 1, 0, 0 };
int cnt = 0;
vector<int> result;
int dfs(int y, int x)
{
// 방문처리
arr[y][x] = 1;
count +1 증가
cnt++;
// 상하좌우 탐색
for (int i = 0; i < 4; i++)
{
int _y = y + dirY[i];
int _x = x + dirX[i];
// 탐색할 수 있는 좌표라면
if (_y >= 0 && _y < m && _x >= 0 && _x < n)
{
// 빈칸이라면(연결할 수 있기 때문에 재귀를 통한 탐색)
if (arr[_y][_x] == 0)
dfs(_y, _x);
}
}
// 개수 반환
return cnt;
}
int main()
{
// 세로, 가로 직사각형 개수
cin >> m >> n >> k;
int x1, x2, y1, y2;
for (int i = 0; i < k; i++)
{
// 왼쪽 아래 꼭짓점과 오른쪽 위 꼭짓점 입력
cin >> x1 >> y1 >> x2 >> y2;
// 꼭짓점을 통해 직사각형 칸 칠하기
for (int y = y1; y < y2; y++)
{
for (int x = x1; x < x2; x++)
{
// 직사각형의 포함되는 칸을 1로 바꿈
arr[y][x] = 1;
}
}
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
// 빈칸(0)이라면
if (arr[i][j] == 0)
{
// DFS를 통해 센 개수를 result Vector에 저장
result.push_back(dfs(i, j));
// 개수 초기화
cnt = 0;
}
}
}
// 오름차순 정렬
sort(result.begin(), result.end());
// 나누어지는 영역의 개수 출력
cout << result.size() << endl;
// 정렬된 각 영역의 넓이 출력
for (int i = 0; i < result.size(); i++)
{
cout << result[i] << ' ';
}
}
코드설명
이런 문제도 단순히 0의 위치를 판단한 후 연결되어 있는 0의 개수를 DFS를 통해 개수를 세어 출력하면 되는 문제이다.
후기
요즘 많은 DFS문제를 풀었는데, 어느정도 풀다보니 정해진 틀 안에서 살짝만 달라지는 느낌을 받았다.
이제 다른 DFS 문제를 접하더라도 쉽게 풀 수 있을 것 같다.