BOJ 2583 영역 구하기
BOJ 2583 영역 구하기
문제
$M \times N$ 격자 위에 그려진 $K$개의 직사각형을 제외한 나머지 영역의 개수와 각 영역의 넓이를 구하기.
$M, N, K \le 100$: 격자의 크기가 매우 작으므로 $O(MN)$ 알고리즘으로 충분히 해결 가능.
Time Limit: 1s / Memory Limit: 128MB.
복잡도 분석
Time Complexity: $O(M \times N + K \times (\text{avg area})) \approx O(MN)$. 모든 칸은 최대 한 번씩 방문됨.
Space Complexity: $O(M \times N)$. 격자 정보를 담는 2차원 배열 공간.
접근법
좌표 주어진 것으로 칠하고 bfs 돌리면서 세면 됨
주의할 점은 칠해지지 않은 부분을 세는것
풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
const int INF = 1e9;
const ll LINF = 1e18;
const int MOD = 998244353; // or 1e9 + 7
#define rep(i, a, b) for (int i = (a); i < (b); ++i)
#define all(x) (x).begin(), (x).end()
int dy[4] = {1,0,-1,0};
int dx[4] = {0,1,0,-1};
int M,N,K;
void print_v(vector<vector<int>> &board){
for(auto e:board){
for(auto e2:e){
cout << e2 << " ";
}
cout << "\n";
}
cout << "\n";
}
int bfs(vector<vector<int>> &board, vector<vector<int>> &visited, int start_y, int start_x){
visited[start_y][start_x] = 1;
deque<pair<int,int>> q;
q.push_back({start_y,start_x});
int c=1;
while (!q.empty()){
auto [y,x] = q.front(); q.pop_front();
rep(i,0,4){
int ny = y+dy[i];
int nx = x+dx[i];
if (0<=ny && ny < M && 0<=nx && nx < N){
if (visited[ny][nx]==0 && board[ny][nx]==0){
q.push_back({ny,nx});
c++;
visited[ny][nx] = 1;
}
}
}
}
return c;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin>>M>>N>>K;
vector<vector<int>> board(M,vector<int> (N));
rep(i,0,K){
// 왼쪽 아래, 오른쪽 위
int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2;
rep(j,y1,y2){ // y2-1, x2-1 까지만 칠해야함
rep(k,x1,x2){
board[j][k] = 1;
}
}
}
// 0 인 영역을 bfs로 카운트
vector<vector<int>> visited(M,vector<int> (N));
vector<int> area;
rep(i,0,M){
rep(j,0,N){
if (board[i][j]==0 && visited[i][j]==0){
int r = bfs(board,visited,i,j);
area.push_back(r);
}
}
}
sort(all(area));
cout << area.size() << "\n";
for(const auto &e:area) cout << e << " ";
return 0;
}
좌표 주어졌을때 색칠할때 y2-y1 순으로 색칠하려고 했던것, 그리고 색칠할때 범위를 y2-1이 아닌 y2까지 칠해야 한다고 생각한 것에서만 한번 틀렸다.
점이 아니라 좌표 안에 네모에 칠하는거라서…
This post is licensed under CC BY 4.0 by the author.