모눈종이에 k 개의 직사각형을 그리고 이 직사각형으로 분리되는 영역이 몇개인지를 구하는 문제이다.
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define SIZE 102
int board[SIZE][SIZE];
bool vis[SIZE][SIZE];
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int m, n, k, x1, y1, x2, y2;
cin >> m >> n >> k;
for (int i = 0; i < k; ++i)
{
cin >> x1 >> y1 >> x2 >> y2;
for (int j1 = x1; j1 < x2; ++j1)
{
for (int j2 = y1; j2 < y2; ++j2)
board[j1][j2]++;
}
}
int num = 0; // 위치의 갯수
vector<int> V; // 각 위치의 크기 저장하는 배열
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if (vis[i][j] || board[i][j] != 0) continue;
num++;
queue<pair<int, int>> Q;
Q.push({ i,j });
vis[i][j] = 1;
int area = 0; // 각 위치의 크기
while (!Q.empty())
{
area++;
auto cur = Q.front(); Q.pop();
for (int dir = 0; dir < 4; ++dir)
{
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (vis[nx][ny] || board[nx][ny] != 0)continue;
vis[nx][ny] = 1;
Q.push({ nx,ny });
}
}
V.push_back(area);
}
}
cout << num << '\n';
sort(V.begin(), V.end());
for (auto e : V)
cout << e << '\n';
/*for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if (board[i][j] == 2)
board[i][j] = 1;
cout << board[i][j] << ' ';
}
cout << '\n';
} */
}
예제 케이스도 맞고 여러가지 반례도 다 맞아서 자신있게 코드를 제출했는데 채점 결과가 틀렸습니다가 계속 나왔다. 이는
if (vis[i][j] || board[i][j] != 0) continue;
모눈종이가 색칠해져있는 부분을 위의 코드로 찾아야하는데
if (vis[i][j] || board[i][j] == 1 || board[i][j] == 2) continue;
로 해서 틀린거였다. 직사각형이 단 두번까지만 쌓이는것도 아닌데 섣부르게 이를 판단하였다.
이런 사소하지만 치명적인 실수들을 자주 하는거 같다. 조금 더 섬세해질 필요가 있어보인다.
bfs 문제를 계속 풀다보니 몇가지 조심해야할 점들이 보인다.
아직까지 엄청 어려운 문제를 푼 것은 아니다. bfs가 어떤것인지 맛을 보면서 점점 정답률이 낮은 문제에 도전해봐야겠다. 구현이 안되더라도 어떠한 로직으로 접근해야 하는지라도 생각을 해보면 좋을거 같다.