https://www.acmicpc.net/problem/4963
섬의 개수
문제
정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오.

한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.
두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러싸여 있으며, 지도 밖으로 나갈 수 없다.
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다.
둘째 줄부터 h개 줄에는 지도가 주어진다. 1은 땅, 0은 바다이다.
입력의 마지막 줄에는 0이 두 개 주어진다.
출력
각 테스트 케이스에 대해서, 섬의 개수를 출력한다.
예제 입력 1 복사
1 1
0
2 2
0 1
1 0
3 2
1 1 1
1 1 1
5 4
1 0 1 0 0
1 0 0 0 0
1 0 1 0 1
1 0 0 1 0
5 4
1 1 1 0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 1 1
5 5
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
0 0
예제 출력 1 복사
0
1
1
3
1
9
풀이
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 W,H;
static int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1};
static int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1};
static int[][] A;
static boolean[][] visited;
static int count;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
while (true){
st = new StringTokenizer(br.readLine());
W = Integer.parseInt(st.nextToken()); // 너비
H = Integer.parseInt(st.nextToken()); // 높이
count = 0;
if(W==0 && H==0) break; // 너비, 높이 둘다 0이면 함수 종료
A = new int[H][W]; // 지도배열
visited = new boolean[H][W]; // 방문여부
// 지도 입력값 받기
for(int i=0; i<H; i++){
st = new StringTokenizer(br.readLine()); // 다음줄
for(int j=0; j<W; j++){
A[i][j] = Integer.parseInt(st.nextToken());
}
}
for(int i=0; i<H; i++){
for(int j=0; j<W; j++){
if(A[i][j] == 1 && !visited[i][j]){
BFS(i,j);
count++;
}
}
}
System.out.println(count);
}
}
private static void BFS(int i, int j){
Queue<int[]> q = new LinkedList<>();
q.add(new int[] {i, j}); // 현재좌표 값 큐에 넣기
visited[i][j] = true; // 방문체크
while (!q.isEmpty()){ // 큐가 빌때까지
int[] now = q.poll(); // 현재 좌표값 poll
for(int k=0; k<8; k++){ // 상하좌우대각선 모두 좌표검사
int x = now[0] + dx[k];
int y = now[1] + dy[k];
if(x>=0 && y>=0 && x<H && y<W){ // 다음 좌표값이 지도 범위내에 있고 방문하지 않았고 섬이라면
if(A[x][y] == 1 && !visited[x][y]){
q.add(new int[] {x,y});
visited[x][y] = true;
}
}
}
}
}
}
- BFS 횟수를 count하는 문제
- 지도 입력 값을 2차원 배열에 받는다.
- 지도를 탐색하면서 섬이 나온다면 BFS탐색을 시작한다.
- 큐에 현재 좌표를 넣는다.
- 큐가 빌때까지 아래 동작을 반복수행한다.
- 큐에서 좌표값을 꺼낸다.(now)
- now 좌표값의 상하좌우대각선까지 8방향 검사하면서 섬이 더 있다면 -> 하나의 섬이다
- 만약 방문하지 않았고 또 섬이라면 큐에 좌표값을 넣어준다.
- 0 0이 나올때까지 계속 문제를 입력받아서 출력해줘야 하므로 종료조건을 꼭 추가해주어야 한다.
'코딩테스트 > 백준' 카테고리의 다른 글
[백준 1976] 여행 가자 (Java) - 유니온 파인드 unionfind (2) | 2025.03.20 |
---|---|
[백준 1717] 집합의 표현 (Java) - 유니온파인드 unionfind (0) | 2025.03.20 |
[백준 2606] 바이러스 (Java) BFS 풀이 (0) | 2025.03.16 |
[백준 2606] 바이러스 (Java) DFS풀이 (0) | 2025.03.16 |
[백준 1012] 유기농 배추 (Java) BFS 풀이 (0) | 2025.03.15 |