문제
차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추 흰 지렁이를 구입하기로 결심한다. 이 지렁이는 배추 근처에 서식하며 해충을 잡아먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추 흰 지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. 한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해있는 것이다.
한나가 배추를 재배하는 땅은 고르지 못해서 배추를 군데군데 심어 놓았다. 배추들이 모여있는 곳에는 배추 흰 지렁이가 한 마리만 있으면 되므로 서로 인접해있는 배추들이 몇 군데에 퍼져있는지 조사하면 총 몇 마리의 지렁이가 필요한지 알 수 있다. 예를 들어 배추밭이 아래와 같이 구성되어 있으면 최소 5마리의 배추 흰 지렁이가 필요하다. 0은 배추가 심어져 있지 않은 땅이고, 1은 배추가 심어져 있는 땅을 나타낸다.
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 |
입력
입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그다음 줄부터 각각의 테스트 케이스에 대해 첫째 줄에는 배추를 심은 배추밭의 가로길이 M(1 ≤ M ≤ 50)과 세로 길이 N(1 ≤ N ≤ 50), 그리고 배추가 심어져 있는 위치의 개수 K(1 ≤ K ≤ 2500)이 주어진다. 그다음 K 줄에는 배추의 위치 X(0 ≤ X ≤ M-1), Y(0 ≤ Y ≤ N-1)가 주어진다. 두 배추의 위치가 같은 경우는 없다.
출력
각 테스트 케이스에 대해 필요한 최소의 배추 흰 지렁이 마리 수를 출력한다.
문제 접근 방법
상하좌우로 맞닿은 배추가 있으면 하나의 그룹으로 취급하여 배추 흰 지렁이를 그 그룹에 아무 곳에나 하나만 놓으면 된다. 문제를 푸는 논리는 다음과 같다.
1. 그룹이 지어지지 않은 배추를 찾는다
2. 1에서 찾은 배추와 같은 그룹인 배추들을 탐색하여 지도에서 지워준다
3. 그룹 선별이 끝나면 해당 그룹에 놓아줄 배추 흰 지렁이의 개수를 +1 해준다.
4. 1~3 과정을 지도 전체를 탐색하여 반복해주면 총 배추 흰 지렁이가 몇 마리 필요한 지 알게 된다.
전혀 다른 조건 없이 같은 그룹인지 판단만 해주면 되므로 어떤 탐색 알고리즘을 사용하던지 상관이 없다.
1. 깊이 우선 탐색(DFS, Depth First Search)
-1. 재귀(Recursion)
-2. 스택 + 반복문(Stack + Loop)
2. 너비 우선 탐색(BFS, Breath First Search)
총 3가지 방법으로 풀어줄 수 있다.
나는 위 코드를 작성할 때 굳이 방문 유무를 판단할 배열을 선언해 줄 필요 없이 그룹을 지으면서 지도에서 지워놓으면 그룹이 지어지지 않은 배추만 1로 남아있으므로 방문 유무를 판단할 수 있다고 생각해서 visited배열 대신 지도에서 지우는 방법으로 방문 유무를 체크했다.
JAVA 코드 풀이
1. 깊이 우선 탐색
-1. 재귀
-2. 스택 + 반복문
2. 너비 우선 탐색
코드 실행 결과
후기
처음 나는 위 문제를 깊이 우선 탐색 DFS(재귀)로 풀었다. 그러고 나서 문제 알고리즘을 보았더니 너비 우선 탐색 BFS로 풀어도 된다길래 BFS도 풀어보고 DFS(Stack + Loop)으로도 풀어 보았다. 이런 문제는 다시 다른 방법으로 풀면서 느끼는 것이지만, 단순히 이어져 있는 것을 탐색만 하면 되는 것이므로 자료형을 다르게 쓰는 것 외에 코드를 딱히 더 바꿀 것이 없다고 느껴진다. 오히려 이번 문제는 로직이 단순해서 재귀로 풀었을 때 효율이 제일 좋게 나온 것 같다. 재귀는 코드를 작성할 때만 편하게 쓸 수 있다고만 생각했지 반복문보다 효율적일 것이라고 상상하지 못했는데 의외의 결과에 다시 재귀에 대해 다시 생각해보게 되었다.
문제 원본
https://www.acmicpc.net/problem/1012
알고리즘 분류
유사한 문제
'문제 풀이 > [JAVA_자바] 백준' 카테고리의 다른 글
[JAVA / 자바] 백준 1697번 - 숨바꼭질 (0) | 2022.02.14 |
---|---|
[JAVA / 자바] 백준 7576번 - 토마토 (0) | 2022.02.11 |
[JAVA / 자바] 백준 2579번 - 계단 오르기 (0) | 2022.02.09 |
[JAVA / 자바] 백준 2606번 - 바이러스 (0) | 2022.02.08 |
[JAVA / 자바] 백준 11726번 - 2xn 타일링 (0) | 2022.02.07 |