2667번: 단지번호붙이기
https://www.acmicpc.net/problem/2667
# DFS 코드
import java.util.*;
import java.io.*;
public class Main {
// 지도 정보 및 방문 여부 체크
static int[][] danji; // 지도 배열 (1: 집, 0: 빈 공간)
static boolean[][] visited; // 해당 좌표를 방문했는지 여부
// 방향벡터: 상하좌우
static int[] dx = {0, 0, -1, 1}; // 행 이동 (위, 아래)
static int[] dy = {-1, 1, 0, 0}; // 열 이동 (좌, 우)
static List<Integer> result; // 단지별 집의 수 저장 리스트
static int cnt, N; // cnt: 단지에 포함된 집 수, N: 지도 크기
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 입력
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 출력
result = new LinkedList<>();
N = Integer.parseInt(br.readLine()); // 지도의 크기 입력
danji = new int[N][N]; // 지도 배열 생성
visited = new boolean[N][N]; // 방문 배열 생성
cnt = 1; // DFS 시작점 포함하므로 1로 초기화
// 지도 정보 입력 받기
for (int i = 0; i < N; i++) {
String str = br.readLine(); // 한 줄 입력
for (int j = 0; j < N; j++) {
danji[i][j] = str.charAt(j) - '0'; // 문자 '0' 또는 '1'을 숫자로 변환
}
}
// 지도 전체를 탐색
for (int x = 0; x < N; x++) {
for (int y = 0; y < N; y++) {
// 집이 있고 아직 방문하지 않았다면 -> 새로운 단지 발견
if (danji[x][y] == 1 && !visited[x][y]) {
dfs(x, y); // DFS 탐색 시작
result.add(cnt); // 단지 내 집 수 리스트에 추가
cnt = 1; // 다음 단지를 위해 cnt 초기화
}
}
}
Collections.sort(result); // 오름차순 정렬
bw.write(result.size() + "\n"); // 단지 수 출력
for (int r : result) {
bw.write(r + "\n"); // 각 단지의 집 수 출력
}
bw.flush();
bw.close();
}
// DFS 함수
public static void dfs(int x, int y) {
visited[x][y] = true; // 현재 좌표 방문 처리
// 상하좌우 탐색
for (int i = 0; i < 4; i++) {
int nx = dx[i] + x; // 다음 x좌표
int ny = dy[i] + y; // 다음 y좌표
// 배열 범위 체크 + 아직 방문 안 했고 + 집(1)이 있을 때만 이동
if (nx >= 0 && ny >= 0 && nx < N && ny < N
&& !visited[nx][ny] && danji[nx][ny] == 1) {
cnt++; // 단지 내 집 개수 증가
dfs(nx, ny); // 다음 집으로 DFS
}
}
}
}
# BFS 코드
import java.io.*;
import java.util.*;
public class Main {
static int[][] map; // 지도 배열 (0: 집 없음, 1: 집 있음)
static boolean[][] visited; // 방문 여부 체크 배열
static int n; // 지도의 크기 (n x n)
static int[] dx = { -1, 1, 0, 0 }; // 행 변화 (상, 하)
static int[] dy = { 0, 0, -1, 1 }; // 열 변화 (좌, 우)
static List<Integer> result = new ArrayList<>(); // 결과를 저장할 리스트 (각 단지에 속한 집의 수)
public static void main(String[] args) throws IOException {
// 입력
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
// 배열 초기화
map = new int[n][n];
visited = new boolean[n][n];
// 지도 입력 받기
for (int i = 0; i < n; i++) {
String line = br.readLine();
for (int j = 0; j < n; j++) {
map[i][j] = line.charAt(j) - '0'; // 문자 '1' → 숫자 1
}
}
// 전체 탐색 시작
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 집이 있고, 아직 방문하지 않았다면 → 새로운 단지 발견!
if (map[i][j] == 1 && !visited[i][j]) {
int count = bfs(i, j); // 단지 하나에 대해 BFS로 연결된 집 수 세기
result.add(count); // 단지리스트에 집 수 저장
}
}
}
// 단지별 집의 수를 오름차순으로 정렬
Collections.sort(result);
// 출력
System.out.println(result.size()); // 단지 수
for (int r : result) {
System.out.println(r); // 각 단지의 집 수
}
}
// BFS 함수: 시작 좌표 (x, y)부터 연결된 집들 탐색
static int bfs(int x, int y) {
Queue<int[]> queue = new LinkedList<>(); // 탐색을 위한 큐 생성
queue.offer(new int[]{x, y}); // 시작점 큐에 넣기
visited[x][y] = true; // 시작점 방문 처리
int count = 1; // 이 단지에 속한 집의 수 (시작점 포함해서 1)
// 큐가 빌 때까지 반복
while (!queue.isEmpty()) {
// 현재 위치 꺼내기
int[] curr = queue.poll();
int currX = curr[0];
int currY = curr[1];
// 상하좌우 방향 탐색
for (int i = 0; i < 4; i++) {
int nextX = currX + dx[i];
int nextY = currY + dy[i];
// 1. 범위 벗어나면 건너뜀
if (nextX < 0 || nextY < 0 || nextX >= n || nextY >= n) {
continue;
}
// 2. 이미 방문했거나, 집이 없는 경우 건너뜀
if (visited[nextX][nextY] || map[nextX][nextY] == 0) {
continue;
}
// 3. 연결된 집이라면
visited[nextX][nextY] = true; // 방문 처리
queue.offer(new int[]{nextX, nextY}); // 큐에 추가
count++; // 집 수 증가
}
}
return count; // 이 단지에 속한 집의 총 개수 반환
}
}
'코딩테스트 > 자바 문제풀이' 카테고리의 다른 글
[CLASS 3: 브루트포스] 백준 6064 카잉 달력 (1) | 2024.11.18 |
---|---|
[CLASS 3: 문자열] 백준 5525 IOIOI (0) | 2024.11.17 |
[CLASS 3: BFS] 백준 2178 미로 탐색 (0) | 2024.11.15 |
[CLASS 3: 그리디] 백준 1931 회의실 배정 (1) | 2024.11.14 |
[CLASS 3: 플로이드 워셜] 백준 1389 케빈 베이컨의 6단계 법칙 (0) | 2024.11.13 |