코딩테스트/BOJ

[BOJ] 2583 영역 구하기 - JAVA

5월._. 2022. 7. 17.
728x90

1. 문제

2583번: 영역 구하기

첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오

www.acmicpc.net

눈금의 간격이 1인 M×N(M,N≤100)크기의 모눈종이가 있다. 이 모눈종이 위에 눈금에 맞추어 K개의 직사각형을 그릴 때, 이들 K개의 직사각형의 내부를 제외한 나머지 부분이 몇 개의 분리된 영역으로 나누어진다.

예를 들어 M=5, N=7 인 모눈종이 위에 <그림 1>과 같이 직사각형 3개를 그렸다면, 그 나머지 영역은 <그림 2>와 같이 3개의 분리된 영역으로 나누어지게 된다.


<그림 2>와 같이 분리된 세 영역의 넓이는 각각 1, 7, 13이 된다.

M, N과 K 그리고 K개의 직사각형의 좌표가 주어질 때, K개의 직사각형 내부를 제외한 나머지 부분이 몇 개의 분리된 영역으로 나누어지는지, 그리고 분리된 각 영역의 넓이가 얼마인지를 구하여 이를 출력하는 프로그램을 작성하시오.


2. 풀이

static 변수

static int M,N,K;
static boolean[][] map;
static int[][] deltas = {{-1,0},{1,0},{0,1},{0,-1}};

메인

1. x1부터 x2, y1부터 y2까지 영역을 표시한다. x2, y2는 오른쪽 위 점이기 때문에 포함하지 않고 반복문을 돌린다.
2. ArrayList에 dfs 결과를 저장한 뒤, 정렬한다.
3. 정렬한 결과를 StringBuilder에 추가하고 출력한다.

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());

M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new boolean[M][N];

int x1,y1,x2,y2;
for(int i=0;i<K;i++){
   st = new StringTokenizer(in.readLine());
   x1 = Integer.parseInt(st.nextToken());
   y1 = Integer.parseInt(st.nextToken());
   x2 = Integer.parseInt(st.nextToken());
   y2 = Integer.parseInt(st.nextToken());

   for(int x=x1;x<x2;x++){
      for(int y=y1;y<y2;y++){
         map[y][x] = true;
      }
   }
}

ArrayList<Integer> list = new ArrayList<>();
for(int y=0;y<M;y++){
   for(int x=0;x<N;x++){
      if(!map[y][x]){
         list.add(dfs(y,x));
      }
   }
}

Collections.sort(list);
StringBuilder sb = new StringBuilder();
sb.append(list.size()).append('\n');
for(int li:list){
   sb.append(li).append(' ');
}
System.out.print(sb);

DFS 탐색

1. cnt는 1이고 map[y][x]를 true로 바꾼다. 방문배열을 따로 만들지 않고 한 번에 처리했다.
2. 다음으로 갈 수 있는 위치에서 dfs재귀호출하고, 그 값을 cnt에 더한다.
3. cnt를 반환한다.

private static int dfs(int y, int x) {
   int cnt = 1;
   map[y][x] = true;
   for(int d=0;d<4;d++){
      int ny = y+deltas[d][0];
      int nx = x+deltas[d][1];
      if(ny>=0 && ny<M && nx >=0 && nx<N && !map[ny][nx]){
         cnt += dfs(ny,nx);
      }
   }
   return cnt;
}

3. 결과

'코딩테스트 > BOJ' 카테고리의 다른 글

[BOJ] 2529 부등호 - JAVA  (0) 2022.07.19
[BOJ] 1541 잃어버린 괄호 - JAVA  (0) 2022.07.18
[BOJ] 2468 안전영역 - JAVA  (0) 2022.07.16
[BOJ] 10799 쇠막대기 - JAVA  (0) 2022.07.15
[BOJ] 1764 듣보잡 - JAVA  (0) 2022.07.14

댓글