일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- Java
- 동적 프로그래밍
- BFS
- DP
- DFS
- 자바
- 데이터베이스
- 개발자취업
- 스프링 핵심 원리 - 기본편
- 백트래킹
- 백준
- 브루트포스
- 항해99
- Til
- 완전탐색
- 코딩테스트준비
- Spring
- lower bound
- 스프링
- 정렬
- 알고리즘
- 네트워크 계층
- 그리디
- 프로그래머스
- 그래프 이론
- BinarySearch
- 그래프
- 우선순위큐
- 트리
- 99클럽
- Today
- Total
AtraFelis's Develop Diary
[99클럽 코테 스터디 8일차 TIL / 백준] 2667 - 단지번호붙이기 (JAVA) 본문
99클럽 코테스터디 8일차 TIL
KeyWord : 그래프 이론, DFS, BFS
문제
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다. 대각선상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다. 지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수를 오름차순으로 정렬하여 출력하는 프로그램을 작성하시오.
입력
첫 번째 줄에는 지도의 크기 N(정사각형이므로 가로와 세로의 크기는 같으며 5≤N≤25)이 입력되고, 그 다음 N줄에는 각각 N개의 자료(0혹은 1)가 입력된다.
출력
첫 번째 줄에는 총 단지수를 출력하시오. 그리고 각 단지내 집의 수를 오름차순으로 정렬하여 한 줄에 하나씩 출력하시오.
풀이
보자마자 DFS 혹은 BFS로 풀 수 있을 것이라 생각이 들었던 문제다.
지도의 1행 1열부터 n행 n열까지 완전 탐색을 진행하면서, 집이 있는 곳, 즉, 1을 만나면 DFS나 BFS를 진행한다. 0일 때는 무시하고 지나간다.
- 완전 탐색 : 지도 내에 존재하는 단지 수
- DFS / BFS : 단지 내 집의 수
이렇게 정리할 수 있다.
여기서 중요한 것은 집이 있는 곳을 방문했을 때 이미 방문 한 곳인지 체크를 해야 한다는 것이다.
(0,1)에서 DFS를 진행한 후에, 다시 완전탐색을 진행하면서 (1,1)을 방문했을 때 또다시 DFS를 진행하게 되면 중복으로 체크되는 문제가 발생한다.
이것만 고려하면 쉽게 풀 수 있는 문제였다.
코드
DFS와 BFS 둘 다 구현해보았다. main 함수에서 주석문만 바꾸면 된다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static boolean[][] visited;
static int[][] matrix;
static int n;
static int area = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
List<Integer> matrix_cnt = new ArrayList<Integer>();
n = Integer.parseInt(br.readLine());
visited = new boolean[n][n];
matrix = new int[n][n];
for (int i = 0; i < n; i++) {
String str = br.readLine();
for (int j = 0; j < n; j++) {
matrix[i][j] = str.charAt(j) - '0';
}
}
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(!visited[i][j] && matrix[i][j] == 1) {
area = 0;
cnt++;
// dfs(i, j);
bfs(i, j);
matrix_cnt.add(area);
}
}
}
Collections.sort(matrix_cnt);
sb.append(cnt).append("\n");
for (Integer i : matrix_cnt) {
sb.append(i).append("\n");
}
System.out.println(sb);
}
static int[] dx = {-1, 0, 1, 0};
static int[] dy = {0, 1, 0, -1};
private static void dfs(int x, int y) {
visited[x][y] = true;
area++;
for (int k = 0; k < 4; k++) {
int nx = x + dx[k];
int ny = y + dy[k];
if(nx < 0 || nx >= n || ny < 0 || ny >= n)
continue;
if(visited[nx][ny])
continue;
if (matrix[nx][ny] == 1) {
dfs(nx, ny);
}
}
}
private static void bfs(int x, int y) {
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{x, y});
visited[x][y] = true;
while(!q.isEmpty()) {
int[] pos = q.poll();
x = pos[0];
y = pos[1];
area++;
for (int k = 0; k < 4; k++) {
int nx = x + dx[k];
int ny = y + dy[k];
if (nx < 0 || nx >= n || ny < 0 || ny >= n)
continue;
if (visited[nx][ny])
continue;
if (matrix[nx][ny] == 1) {
visited[nx][ny] = true;
q.add(new int[]{nx, ny});
}
}
}
}
}
성능
둘 모두 시간복잡도는 $O(n)$으로 별 차이 없는 것을 확인할 수 있다.
'Algorithm > 백준' 카테고리의 다른 글
[99클럽 코테 스터디 10일차 TIL / 백준] 2573- 빙산(JAVA) (0) | 2025.01.24 |
---|---|
[99클럽 코테 스터디 9일차 TIL / 백준] 1707 - 이분 그래프 (JAVA) (0) | 2025.01.23 |
[99클럽 코테 스터디 7일차 TIL / 백준] 1697 - 숨바꼭질 (JAVA) (0) | 2025.01.22 |
[99클럽 코테 스터디 6일차 TIL / 백준] 1260 - DFS와 BFS (JAVA) (0) | 2025.01.20 |
[99클럽 코테 스터디 5일차 TIL / 백준] 2470 - 두 용액 (JAVA) (0) | 2025.01.17 |