https://www.acmicpc.net/problem/21938

이 문제는 영상 처리와 관련된 문제로, 주어진 이미지에서 각 픽셀의 색상(RGB)을 평균내어, 경계값 T를 기준으로 이진화(Thresholding) 처리를 한 후, 이진화된 이미지에서 물체(255로 인식되는 영역)의 개수를 찾는 문제입니다.
N x M을 입력받고, 각 픽셀의 RGB 값을 읽어옵니다.map[][] 배열에 저장합니다.T를 기준으로, 평균값이 T 이상이면 255(물체), 그렇지 않으면 0(배경)으로 설정합니다.visited[][] 배열에 기록하여 중복 탐색을 방지합니다.import java.util.*;
import java.io.*;
public class Main {
static int n, m, t;
static int map[][];
static boolean visited[][];
static int cnt;
// 방향 벡터 (상, 우, 하, 좌)
static int dy[] = {-1, 0, 1, 0};
static int dx[] = {0, 1, 0, -1};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
// 입력 처리
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
// 이미지 맵 및 방문 기록 배열 초기화
map = new int[n][m];
visited = new boolean[n][m];
// RGB 입력을 받아 평균값을 계산하여 map에 저장
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
// 픽셀의 R, G, B 값 입력
int r = Integer.parseInt(st.nextToken());
int g = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
// RGB 평균값을 map에 저장
map[i][j] = (r + g + b) / 3;
}
}
// 경계값 T 입력
t = Integer.parseInt(br.readLine());
// T 이상인 경우 255로, 미만인 경우 0으로 이진화
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] >= t) {
map[i][j] = 255; // 물체
} else {
map[i][j] = 0; // 배경
}
}
}
// 물체의 개수를 세기 위한 DFS 탐색
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// 물체(255)이고, 방문하지 않은 경우
if (map[i][j] == 255 && !visited[i][j]) {
dfs(i, j); // 물체 탐색
cnt++; // 물체 개수 증가
}
}
}
// 결과 출력: 총 물체의 개수
System.out.println(cnt);
}
// DFS로 물체 탐색 (연결된 255인 영역 탐색)
private static void dfs(int y, int x) {
// 방문 처리
visited[y][x] = true;
// 4방향 탐색 (상, 우, 하, 좌)
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
// 배열 범위 체크
if (ny < 0 || nx < 0 || ny >= n || nx >= m) continue;
// 물체(255)이고, 아직 방문하지 않은 경우 DFS 호출
if (map[ny][nx] == 255 && !visited[ny][nx]) {
dfs(ny, nx);
}
}
}
}
n x m 크기의 배열에 대해 모든 픽셀에 대해 RGB 값을 평균내는 작업은 O(n * m)입니다.T와 비교하여 배열 값을 255 또는 0으로 변경하는 작업 역시 O(n * m)입니다.map[][]:n x m 크기의 배열을 사용하므로 O(n * m)의 공간이 필요합니다.visited[][]:visited 배열 역시 O(n * m)의 공간을 차지합니다.T를 기준으로 255와 0으로 변환하는 작업.map[][]: 각 픽셀의 평균값 및 이진화 값을 저장하는 배열.visited[][]: 각 픽셀의 방문 여부를 기록하는 배열.visited[][] 배열을 사용하지 않고, map[][] 배열의 값을 255에서 -1로 변환하여 이미 탐색한 물체의 픽셀을 표시하는 방법으로 메모리 사용을 줄일 수 있습니다.DFS 대신 반복 구조의 DFS(명시적 스택 사용)를 적용하면 스택 오버플로우를 방지할 수 있습니다.