https://www.acmicpc.net/problem/2667
문제


풀이
입력한 배열을 모두 순회하면서 집이 있는지 없는지 판단해야 하기 때문에 DFS를 활용했다
apart 배열과 똑같은 크기의 visited 배열을 만들고 해당 노드 방문 여부를 체크하였다
총 단지 수는 몇 개가 나올 지 모르기 때문에 ArrayList로 선언하였다
상하좌우를 탐색하기 위해 dx, dy 배열을 활용하여 dfs 탐색을 하였다
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
public class Ureca {
static int N;
static int[][] apart;
static int[] dx = {0, 1, 0, -1}; // 좌우
static int[] dy = {1, 0, -1, 0}; // 상하
static boolean[][] visited;
static ArrayList<Integer> list = new ArrayList<>();
static int count;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
// 지도 크기 입력
N = Integer.parseInt(br.readLine());
apart = new int[N][N];
visited = new boolean[N][N];
// 단지 집 입력 - 1은 집 있음, 0은 없음
for (int i = 0; i < N; i++) {
String line = br.readLine();
for (int j = 0; j < N; j++) {
apart[i][j] = line.charAt(j) - '0';
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// 배열의 값이 1이거나 방문하지 않은 노드일 때만
if (apart[i][j] == 1 && !visited[i][j]) {
// 같은 단지를 세기 위한 변수
count = 1;
// dfs 호출
dfs(i, j);
// 리스트에 같은 단지 내 집 수를 추가
list.add(count);
}
}
}
// 오름차순으로 정렬
Collections.sort(list);
// 총 단지 수와 단지 내 집 수를 출력
sb.append(list.size()).append("\n");
for (Integer i : list) {
sb.append(i).append("\n");
}
System.out.println(sb);
br.close();
}
static void dfs(int x, int y) {
// 방문 처리
visited[x][y] = true;
for (int i = 0; i < 4; i++) {
// 상하좌우 탐색
int nx = x + dx[i];
int ny = y + dy[i];
// nx, ny 값이 배열 인덱스 내에 있고
if (nx >= 0 && ny >= 0 && nx < N && ny < N) {
// 그 자리에 집이 있고 방문하지 않은 노드일 경우에만
if (apart[nx][ny] == 1 && !visited[nx][ny]) {
// dfs 수행
dfs(nx, ny);
// 집 수를 증가
count++;
}
}
}
}
}
결과
