문제
차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추흰지렁이를 구입하기로 결심한다. 이 지렁이는 배추근처에 서식하며 해충을 잡아 먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추 흰지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. 한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해있는 것이다.
한나가 배추를 재배하는 땅은 고르지 못해서 배추를 군데군데 심어놓았다. 배추들이 모여잇는 곳에는 배추 흰 지렁이가 한 마리만 있으면 되므로 서로 인접해 있는 배추들이 몇 군데에 퍼져있는지 조사하면 총 몇 마리의 지렁이가 필요한지 알 수 있다. 예를 들어 배추밭이 아래와 같이 구성되어 있으면 최소 5마리의 배추흰지렁이가 필요하다 0은 배추가 심어져있지 않은 땅이고, 1은 배추가 심어져있는 땅을 나타낸다.
입력
2
10 8 17
0 0
1 0
1 1
4 2
4 3
4 5
2 4
3 4
7 4
8 4
9 4
7 5
8 5
9 5
7 6
8 6
9 6
10 10 1
5 5
해당 문제는 단지번호붙히기와 거의 유사한 문제였다.
이런 문제들은 main에서 bfs메소드를 여러번 호출해야한다. 그래야만 상하좌우를 탐색하여 끊기는지 안 끊기는지 체크할 수 있다.
처음에 0,0 이 들어가면 map[0][0] = 1 이고 첫 방문이므로 바로 통과하면서 bfs에 들어간다.
bfs 메소드는 해당 x,y를 받아서 상하좌우 값이 1(즉, 배추가 심어졌다면) 계속 탐색해나간다. 이 과정에서 모두 방문한 곳은 방문처리를 해버린다. 그러고 나서 상하좌우에 1이 연결된 곳을 다 탐색하고 나면 다시
해당 for문으로 돌아와 카운트 +1 을 한다. 그러면서 점차 계속 x,y를 탐색하는데 처음 시작했던 bfs 때문에
해당 1들은 if문에서 걸러진다. 그러고 계속 1을 찾아가다가
가운데 1을 발견하고 bfs메소드를 다시 실행한다. 이 과정에서 또 위에 과정을 반복하면서 계속 탐색해나간다.
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 Main {
static int count;
static int dx[] = {1,0,-1,0};
static int dy[] = {0,1,0,-1};
static int map[][];
static int M,N;
static boolean visited[][];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int A = Integer.parseInt(br.readLine());
StringTokenizer st;
for(int i =0;i<A;i++){
st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken()); //배추밭 가로
N = Integer.parseInt(st.nextToken()); //배추밭 세로
int K = Integer.parseInt(st.nextToken()); //배추 심어진 개수
map = new int[M][N];
visited = new boolean[M][N];
for (int j = 0; j < K; j++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
map[x][y] = 1;
}
count = 0;
for (int j = 0; j < M ; j++) {
for (int k = 0; k < N; k++) {
if(map[j][k] == 1 && !visited[j][k]){
bfs(j,k);
count++;
}
}
}
System.out.println(count);
}
}
private static void bfs(int j,int k) {
Queue<Node> queue = new LinkedList<>();
queue.add(new Node(j,k));
visited[j][k] =true;
while (!queue.isEmpty()){
Node now = queue.poll();
for (int i = 0; i < 4; i++) {
int nextX = now.x + dx[i];
int nextY = now.y + dy[i];
if(nextX >= 0 && nextY >= 0 && nextX < M && nextY < N){
if(!visited[nextX][nextY]){
if(map[nextX][nextY] == 1){
queue.add(new Node(nextX,nextY));
visited[nextX][nextY] = true;
}
}
}
}
}
}
static class Node{
int x;
int y;
public Node(int x,int y){
this.x = x;
this.y = y;
}
}
}
'알고리즘' 카테고리의 다른 글
백준 No.18352특정 거리의 도시 찾기 - JAVA (0) | 2023.02.28 |
---|---|
백준 No.1417 국회의원 선거 - JAVA (0) | 2023.02.27 |
백준 No.1261 알고스팟 - JAVA (0) | 2023.02.27 |
백준 No.13549 숨바꼭질 3 - JAVA (0) | 2023.02.26 |
백준 No.2665 미로만들기 - JAVA (0) | 2023.02.25 |