본문 바로가기

카테고리 없음

백준온라인저지(BOJ)/#2583/DFS/영역구하기

반응형

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;
}

 

반응형