Algorithm/백준
[백준] 2583 영역구하기
SSONGMI
2021. 4. 9. 16:26
반응형
문제 출처: www.acmicpc.net/problem/2583
2583번: 영역 구하기
첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오
www.acmicpc.net
: 주어진 좌표를 기준으로 빈 영역들이 나눠지고 이러한 빈 영역들이 모두 몇개인지와 그 크기를 오름차순으로 출력해야한다.
: BFS 방식으로 풀이할 수 있다.
: 우선 좌표들을 입력받은 후 map 배열에 1로 표시한다.
: 그 후 다시 map을 순회하며 0인 곳을 만나게 되면 그 좌표부터 델타탐색을 진행하며 사이즈를 계산한다.
: 각 지점을 순회할 때마다 방문 배열에 표시해서 재방문하는 일이 없도록 한다.
: 모든 지점 순회가 끝나면 그 개수를 출력하고 사이즈들을 오름차순으로 정렬하여 출력한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringBuilder sb = new StringBuilder();
static StringTokenizer st;
static int R, C, K;
static int[][] map;
static boolean[][] v;
static class Point{
int r, c, cnt;
public Point(int r, int c) {
super();
this.r = r;
this.c = c;
}
}
public static void main(String[] args) throws IOException {
st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new int[R][C];
v = new boolean[R][C];
for(int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int sc = Integer.parseInt(st.nextToken());
int sr = Integer.parseInt(st.nextToken());
int dc = Integer.parseInt(st.nextToken());
int dr = Integer.parseInt(st.nextToken());
fill(sr, sc, dr, dc);
}
int cnt = 0;
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < R; i++) {
for(int j = 0; j < C; j++) {
if(map[i][j] == 0 && !v[i][j]) {
cnt++;
list.add(bfs(i, j));
}
}
}
System.out.println(cnt);
Object[] ans = list.toArray();
Arrays.sort(ans);
for(int i = 0, size = ans.length; i <size; i++ ) {
System.out.print(ans[i] + " ");
}
}
private static int[] dr = {-1, 1, 0, 0};
private static int[] dc = {0, 0, -1, 1};
private static int bfs(int i, int j) {
Queue<Point> q = new LinkedList<>();
q.offer(new Point(i, j));
map[i][j] = 1;
v[i][j] = true;
int cnt = 0;
while(!q.isEmpty()) {
Point cur = q.poll();
cnt++;
for(int k = 0; k < 4; k++) {
int nr = cur.r + dr[k];
int nc = cur.c + dc[k];
if(nr < 0 || nr >= R || nc < 0 || nc >= C || map[nr][nc] == 1 || v[nr][nc]) continue;
v[nr][nc] = true;
q.offer(new Point(nr, nc));
}
}
return cnt;
}
private static void fill(int sr, int sc, int dr, int dc) {
for(int r = sr; r < dr; r++) {
for(int c = sc; c < dc; c++) {
map[r][c] = 1;
}
}
}
}
반응형