반응형
https://www.acmicpc.net/problem/2583
2583번: 영역 구하기
첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오른쪽 위 꼭짓점의 x, y좌표값이 빈칸을 사이에 두고 차례로 주어진다. 모눈종이의 왼쪽 아래 꼭짓점의 좌표는 (0,0)이고, 오른쪽 위 꼭짓점의 좌표는(N,M)이다. 입력되는 K개의 직사각형들이 모눈종이 전체를 채우는 경우는 없다.
www.acmicpc.net
영역 구하기 문제다.
마찬가지로 2차원 좌표에서의 DFS탐색을 필요로 한다.
모눈종이에 그려진 직사각형의 영역만큼 마킹을 한 뒤(board[][]++),
마킹이 되어있지 않은 나머지 부분에 대해서 DFS 를 하면 된다.
[구현 코드]
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector<vector<int>> board;
const int dy[] = {0, 0, -1, 1};
const int dx[] = {-1, 1, 0, 0};
int N,M,area;
void dfs(int y, int x){
board[y][x] = 1;
area++;
for(int m = 0; m < 4; m++){
//board[next_y][next_x]는 먼저 next_y ,next_x 좌표의 범위를 설정하고 다음줄에 꼭 적어야함
if((y+dy[m])>=0 && (y+dy[m]<M)
&&(x+dx[m])>=0 && (x+dx[m]<N)
&&(board[y+dy[m]][x+dx[m]]==0)){
dfs(y+dy[m],x+dx[m]);
}
}
}
int main(){
int K;
vector<int> ret;
cin>>M>>N>>K; // M은 y좌표, N은 x좌표
board.resize(M,vector<int>(N,0));
//먼저 모눈종이로 마킹한 직사각형 부분을 표시해준다.
for(int i = 0; i < K; i++){
int x1, x2, y1, y2;
cin>>x1>>y1>>x2>>y2;
for(int j = y1; j < y2; j++){
for(int k = x1; k < x2; k++){
board[j][k]++;
}
}
}
//마킹되지 않은 나머지 부분에 대해 DFS를 시행한다.
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
if(board[i][j]==0){
area = 0;
dfs(i,j);
ret.push_back(area);
}
}
}
sort(ret.begin(), ret.end());
cout<<ret.size()<<'\n';
for(int i = 0; i < ret.size(); i++){
cout<<ret[i]<<" ";
}
return 0;
}
반응형