[Java] 백준(실버-1) 1926번 - 그림
문제 풀이
이 문제는 너비 우선 탐색인 BFS를 통해 쉽게 풀 수 있다.
아이디어 도출
문제에서 요구하는 총 그림의 개수와 모든 그림 중 가장 큰 넓이를 구하면 된다. 이를 위해 생각한 아이디어는 다음과 같다.
- 입력받은 도화지 배열에서 색칠된 노드를 탐색하는데, BFS를 통해 상,하,좌,우로 탐색하며 연결된 그림을 찾는다.
- 이때, 새로운 그림을 찾을 떄마다 카운트하면 총 그림의 개수를 구할 수 있다.
- 하나의 그림에서 연결된 그림 노드를 찾을 때, 노드 위치에 +1씩 저장하여 그림의 넓이를 저장해놓는다.
- 그림마다 구한 넓이를 비교해가며 총 그림 중 가장 큰 넓이를 구할 수 있다,
문제 풀이를 위해 작성한 코드는 아래와 같다.
작성코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import java.io.*;
import java.util.*;
class Main {
// 입력 N, M 선언
static int N;
static int M;
// 상하좌우를 탐색하기 위한 dx, dy 배열 선언
static int[] dx = new int[]{0, 1, 0, -1};
static int[] dy = new int[]{1, 0, -1, 0};
// 방문 배열 선언
static boolean[][] visited;
// 입력 도화지 배열 선언
static int[][] arr;
// 그림의 총 개수를 구할 cnt, 그림별 넓이를 구할 area, 모든 그림 중 가장 큰 넓이를 가질 max 변수 선언
static int cnt;
static int area;
static int max;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
// 방문 배열 및 도화지 배열 초기화
visited = new boolean[N][M];
arr = new int[N][M];
// 입력값을 통해 도화지 배열 갱신
for(int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<M; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
// 구할 그람의 개수와 가장 큰 그림의 넓이를 구하기 위해 cnt, area 초기화
cnt = 0;
// 도화지 배열을 돌며 그림의 개수를 찾기 위한 BFS 함수를 호출한다.
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(!visited[i][j]) {
if(arr[i][j] != 0) {
// 그림별 넓이를 계산하기 위한 area 초기화
area = 1;
// BFS 호출하여 i, j 위치부터 순회
BFS(i, j);
// 그림별 area를 비교하여 가장 더 큰 넓이를 max에 저장
max = Math.max(area, max);
}
}
}
}
bw.write(cnt+"\n");
bw.write(max+"\n");
bw.close();
br.close();
}
static void BFS(int x, int y) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[]{x, y});
visited[x][y] = true;
// 그림의 개수 카운트
cnt++;
while(!q.isEmpty()) {
int[] now = q.poll();
for(int dir=0; dir<4; dir++) {
int i = now[0] + dx[dir];
int j = now[1] + dy[dir];
if(0<=i && 0<=j && i<N && j<M) {
if(!visited[i][j] && arr[i][j] != 0) {
visited[i][j] = true;
// 그릴마다 연결노드의 넓이를 저장
area++;
arr[i][j] = area;
q.add(new int[]{i, j});
}
}
}
}
}
}
출처
- 해당 문제의 저작권은 문제를 만든이에게 있으며 자세한 내용은 문제 링크에서 참조바랍니다.