자바칩
[백준 / Java] 1743: 음식물 피하기 (BFS) 본문
난이도: Silver 1
문제: https://www.acmicpc.net/problem/1743
문제
코레스코 콘도미니엄 8층은 학생들이 3끼의 식사를 해결하는 공간이다. 그러나 몇몇 비양심적인 학생들의 만행으로 음식물이 통로 중간 중간에 떨어져 있다. 이러한 음식물들은 근처에 있는 것끼리 뭉치게 돼서 큰 음식물 쓰레기가 된다.
이 문제를 출제한 선생님은 개인적으로 이러한 음식물을 실내화에 묻히는 것을 정말 진정으로 싫어한다. 참고로 우리가 구해야 할 답은 이 문제를 낸 조교를 맞추는 것이 아니다.
통로에 떨어진 음식물을 피해가기란 쉬운 일이 아니다. 따라서 선생님은 떨어진 음식물 중에 제일 큰 음식물만은 피해 가려고 한다.
선생님을 도와 제일 큰 음식물의 크기를 구해서 “10ra"를 외치지 않게 도와주자.
입력
첫째 줄에 통로의 세로 길이 N(1 ≤ N ≤ 100)과 가로 길이 M(1 ≤ M ≤ 100) 그리고 음식물 쓰레기의 개수 K(1 ≤ K ≤ N×M)이 주어진다. 그리고 다음 K개의 줄에 음식물이 떨어진 좌표 (r, c)가 주어진다.
좌표 (r, c)의 r은 위에서부터, c는 왼쪽에서부터가 기준이다. 입력으로 주어지는 좌표는 중복되지 않는다.
출력
첫째 줄에 음식물 중 가장 큰 음식물의 크기를 출력하라.
BFS 알고리즘을 잘 이해했으면 쉽게 풀 수 있는 문제다.
크기를 체크할 때는 크기 체크 변수 count를 2로 초기화해서 새로운 칸에 방문할 때마다 count를 1씩 증가시키면 된다.
그리고 마지막에 방문한 (x, y)에 설정된 숫자를 최댓값 변수에 갱신하면 된다.
주석에 한 줄 한줄 설명을 자세히 적어 놓았다.
코드를 바로 보자.
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class P1743_음식물피하기 {
static int N, M; // 통로의 세로, 가로 길이
static int[] dx = {-1, 0, 1, 0}; // 상, 하 이동
static int[] dy = {0, -1, 0, 1}; // 좌, 우 이동
static int[][] area; // 2차원 통로 배열
static boolean[][] visited; // 2차원 방문 배열
static int max; // 가장 큰 음식물의 크기
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 통로의 세로 길이 입력 받기
M = Integer.parseInt(st.nextToken()); // 통로의 가로 길이 입력 받기
int K = Integer.parseInt(st.nextToken()); // 음식물 쓰레기의 개수
area = new int[N + 1][M + 1]; // 통로 배열 세로, 가로 크기 초기화
visited = new boolean[N + 1][M + 1]; // 방문 배열 세로, 가로 크기 초기화
// 통로 배열 초기화
for (int k = 0; k < K; k++) {
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken()); // 음식물의 x좌표
int c = Integer.parseInt(st.nextToken()); // 음식물의 y좌표
area[r][c] = 1; // 해당 좌표에 음식물 생성
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
// 해당 칸을 방문하지 않았거나, 해당 칸에 음식물이 있다면
if (!visited[i][j] && area[i][j] != 0) {
bfs(i, j); // 해당 칸부터 bfs 수행
}
}
}
System.out.println(max); // 가장 큰 음식물의 크기 출력
}
public static void bfs(int a, int b) {
Queue<int[]> queue = new LinkedList<>(); // bfs 수행을 위한 큐 생성
queue.add(new int[] {a, b}); // 현재 칸을 큐에 삽입
visited[a][b] = true; // 현재 칸을 방문 체크
int count = 2; // 현재 칸은 1이고, 다음 칸부터 2로 체크할 카운트
while (!queue.isEmpty()) {
int[] now = queue.poll(); // 현재 칸을 큐에서 뽑기
for (int i = 0; i < 4; i++) {
int x = now[0] + dx[i]; // 인접 칸의 x좌표
int y = now[1] + dy[i]; // 인접 칸의 y좌표
// 인접 칸의 인덱스가 유효하지 않다면 건너뛰기
if (x < 1 || y < 1 || x > N || y > M) {
continue;
}
// 인접 칸을 이미 방문했거나, 음식물 쓰레기가 없는 칸이라면 건너뛰기
if (visited[x][y] || area[x][y] == 0) {
continue;
}
queue.add(new int[] {x, y}); // 인접 칸을 큐에 삽입
visited[x][y] = true; // 인접 칸을 방문 체크
area[x][y] = count++; // 인접 칸 카운트 1 증가
a = x; // 최근 방문한 x좌표 갱신
b = y; // 최근 방문한 y좌표 갱신
}
}
max = Math.max(max, area[a][b]); // 음식물의 최댓값 갱신
}
}
|
cs |
'알고리즘 > 백준' 카테고리의 다른 글
[백준 / Java] 9205: 맥주 마시면서 걸어가기 (BFS) (0) | 2024.06.23 |
---|---|
[백준 / Java] 14940: 쉬운 최단거리 (BFS) (0) | 2024.06.18 |
[백준 / Java] 1926: 그림 (BFS) (0) | 2024.06.14 |
[백준 / Java] 2583: 영역 구하기 (BFS) (1) | 2024.06.13 |
[백준 / Java] 13913: 숨바꼭질 4 (BFS) (0) | 2024.06.09 |