츄르사려고 코딩하는 코집사입니다.
1. [백준 알고리즘] 백준 2583번 영역 구하기 자바(Java)
1) 문제번호 : 2583번
2) 문제 출처
2. 문제
눈금의 간격이 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개의 직사각형 내부를 제외한 나머지 부분이 몇 개의 분리된 영역으로 나누어지는지, 그리고 분리된 각 영역의 넓이가 얼마인지를 구하여 이를 출력하는 프로그램을 작성하시오.
3. 제약사항
-
4. 입력
첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오른쪽 위 꼭짓점의 x, y좌표값이 빈칸을 사이에 두고 차례로 주어진다. 모눈종이의 왼쪽 아래 꼭짓점의 좌표는 (0,0)이고, 오른쪽 위 꼭짓점의 좌표는(N,M)이다. 입력되는 K개의 직사각형들이 모눈종이 전체를 채우는 경우는 없다.
5. 출력
첫째 줄에 분리되어 나누어지는 영역의 개수를 출력한다. 둘째 줄에는 각 영역의 넓이를 오름차순으로 정렬하여 빈칸을 사이에 두고 출력한다.
6. 풀이
- 간단한 DFS 문제다.
- 직사각형의 좌표를 준 것에서 직사각형의 영역을 1로 배열에 입력한다.
- 그래서 전체 배열을 돌면서 만약에 배열값이 0이라면 DFS를 도는데, 배열값이 0일 때마다 영역의 넓이를 구하는 count를 1씩 증가하여 DFS가 끝나면 ArrayList에 값을 넣어준다.
- 배열을 완전탐색하면 ArrayList에는 영역의 넓이가 들어가는데, 넓이의 개수를 구하면 그게 직사각형의 개수가 되고, ArrayList를 오름차순으로 정렬하여 출력하면 된다.
7. 소스 코드
import java.io.*;
import java.util.*;
public class Main {
static int M; // 높이
static int N; // 너비
static int K; //직사각형 개수
static int[] dr = {-1, 1, 0, 0}; //상하좌우
static int[] dc = {0, 0, -1, 1}; //상하좌우
static int[][] map; // 지도
static int count = 0; // 영역 구하기
static ArrayList<Integer> List;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
M = sc.nextInt(); //map 높이
N = sc.nextInt(); //map 너비
K = sc.nextInt(); //직사각형 개수
map = new int[M][N]; //map
//직사각형 구해서 영역들 1로 넣기
for(int i=0;i<K;i++) {
int x1 = sc.nextInt();
int y1 = sc.nextInt();
int x2 = sc.nextInt();
int y2 = sc.nextInt();
for(int a=y1;a<y2;a++) {
for(int b=x1;b<x2;b++) {
map[a][b] = 1;
}
}
}
List = new ArrayList<Integer>(); // 그 영역 넓이 저장
for(int i=0;i<M;i++) {
for(int j=0;j<N;j++) {
if(map[i][j]==0) {
count = 0;
DFS(i,j);
List.add(count);
}
}
}
//List에 들어간 넓이의 개수를 구하면 그게 직사각형의 개수
System.out.println(List.size());
Collections.sort(List);
for(Integer c : List) System.out.print(c + " ");
}
public static void DFS(int r, int c) {
map[r][c] = 1;
count++;
for(int i=0;i<4;i++) {
int nr = r + dr[i];
int nc = c + dc[i];
if(nr>=0 && nc >=0 && nr<M && nc<N) {
if(map[nr][nc]==0) DFS(nr,nc);
}
}
}
}
'알고리즘 > 백준 알고리즘' 카테고리의 다른 글
[백준 알고리즘] 백준 1965번 상자넣기 자바(Java) (0) | 2021.04.13 |
---|---|
[백준 알고리즘] 백준 1018번 체스판 다시 칠하기 자바(Java) (0) | 2021.04.13 |
[백준 알고리즘] 백준 13305번 주유소 자바(Java) (0) | 2021.04.12 |
[백준 알고리즘] 백준 14659번 한조서열정리하고옴ㅋㅋ 자바(Java) (0) | 2021.04.12 |
[백준 알고리즘] 백준 3085번 사탕게임 자바(Java) (0) | 2021.04.08 |
[백준 알고리즘] 백준 14910번 오르막 자바(Java) (0) | 2021.04.08 |
[백준 알고리즘] 백준 17496번 스타후르츠 자바(Java) (0) | 2021.04.07 |
[백준 알고리즘] 백준 15489번 파스칼 삼각형 자바(Java) (0) | 2021.04.04 |
최근댓글