![](https://blog.kakaocdn.net/dn/IRgxJ/btrFXXDgDFL/f6iK5p1odCtJuv3qf1zzX1/img.jpg)
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개의 분리된 영역으로 나누어지게 된다.
![](https://blog.kakaocdn.net/dn/rPlMo/btrFY7egmmf/sUyyM9tc1VjB8IhllQvom1/img.png)
<그림 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. 결과
![](https://blog.kakaocdn.net/dn/dHsegB/btrFYvTV5IH/jWSZ24l4KZZ2bJtSczAt20/img.png)
'코딩테스트 > 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 |
댓글