본문 바로가기

algorithm

백준 2583번 영역 구하기

https://www.acmicpc.net/problem/2583

 

아이디어:

1. 직사각형 k에 대해 board[i][j] = 1 로 하고 2중 for문으로 board[i][j] == 0 && vis[i][j] == 0 을 찾아 큐에 넣으면서 BFS

2. 큐에 넣으면서 num++; 넓이로 저장할 area는 큐에서 빼면서 ++한 뒤, area가 0이 아닐 때 벡터 areas에 삽입

3. 벡터 areas를 sort()로 정렬해서 num 뒤에 출력

 

n과 m이 각각 y축, x축을 가리 키는 것에 주의

y축에서, 그림을 상하 반전 시켜도 넓이는 그대로이므로

문제 그림에 충실해서 for문을 반대로 돌리는 등 별도 처리하지 않아도 된다.

 

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

char board[1001][1001];
int vis[1001][1001];
int m, n;
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };

int main() {

	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	int k, x1, x2, y1, y2;
	int num = 0, area = 0;
	cin >> m >> n >> k;
	queue<pair<int, int>> Q;
	vector<int> areas;

	while (k--) {
		cin >> x1 >> y1 >> x2 >> y2;
		for (int i = y1; i < y2; i++) {
			for (int j = x1; j < x2; j++) {
				board[i][j] = 1;
			}
		}
	}

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {

			area = 0;

			if (board[i][j] == 0 && vis[i][j] == 0) {
				vis[i][j] = 1;
				Q.push({ i, j });
				num++;
			}

			while (!Q.empty()) {
				pair<int, int> cur = Q.front();
				Q.pop();
				area++;

				for (int dir = 0; dir < 4; dir++) {
					int nx = cur.first + dx[dir];
					int ny = cur.second + dy[dir];
					if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
					if (board[nx][ny] != 0 || vis[nx][ny] != 0) continue;
					vis[nx][ny] = 1;
					Q.push({ nx, ny });
				}
			}

			if (area) areas.push_back(area);
		}
	}

	cout << num << "\n";
	sort(areas.begin(), areas.end());
	for (auto x : areas) cout << x << " ";

	return 0;
}

'algorithm' 카테고리의 다른 글

백준 2468번 안전 영역  (0) 2025.05.07
백준 5014번 스타트링크  (0) 2025.04.27
백준 5427번 불  (0) 2025.04.12
백준 7562번 나이트의 이동  (0) 2025.04.12
백준 7569번 토마토  (0) 2025.04.12