문제
정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오.
한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.
두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러싸여 있으며, 지도 밖으로 나갈 수 없다.
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다.
둘째 줄부터 h개 줄에는 지도가 주어진다. 1은 땅, 0은 바다이다.
입력의 마지막 줄에는 0이 두 개 주어진다.
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
출력
각 테스트 케이스에 대해서, 섬의 개수를 출력한다.
0
1
1
3
1
9
풀이
- 말 그대로 '섬'의 개수를 세는 문제. 바다에 독립적으로 떠 있는 땅을 세면된다. 즉 상하좌우대각 방향으로 이어진 땅은 같은 섬이다.
- DFS 탐색을 하면서 상하좌우대각 방향을 확인한다.
- 맵의 범위를 주의하자.
코드
public class Problem9 {
static int width;//지도 가로
static int height;// 지도 세로
static int[][] map; //2차웝 배열인 지도
//아래, 위, 오른쪽, 왼쪽, 왼쪽 위, 오른쪽 아래, 왼쪽 아래, 오른쪽 위
static int[] mx = {0,0,1,-1,-1,1,-1,1};
static int[] my = {1,-1,0,0,-1,1,1,-1};
static boolean [][] visit; //방문 여부
static int result; //섬의 개수
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(true){
width = scan.nextInt();
height = scan.nextInt();
if(width == 0 && height ==0) // 종료 조건
System.exit(0);
map = new int[width][height];
visit = new boolean[width][height];
for(int i = 0;i < height;i++) { //지도 입력
for(int j = 0; j < width; j++) {
map[height][width]= scan.nextInt();
}
}
result = 0;
//섬의 개수 체크 DFS 이용
for(int i = 0;i < height;i++) {
for(int j = 0; j < width; j++) {
if(map[i][j]== 1 && !visit[i][j]) {
check(i,j);
result++;
}
}
}
System.out.println(result);
}
}
//DFS
private static void check(int x, int y) {
visit[x][y] = true;
//상하좌우대각 방향 확인
for(int i = 0; i < 8; i++) {
int nx = x + mx[i];
int ny = y + my[i];
//지도 안에 있고 맵 요소가 1인 자리
if(nx >= 0 && ny>= 0 && nx < height && ny < width) {
if(map[nx][ny] == 1 && !visit[nx][ny])
check(nx,ny);
}
}
}
}
'Computer Science > 알고리즘' 카테고리의 다른 글
[백준] 1987번: 알파벳_JAVA (0) | 2023.02.13 |
---|---|
[백준] 11724번: 연결 요소의 개수_JAVA (0) | 2023.02.13 |
[백준] 1182번: 부분수열의 합_JAVA (0) | 2023.02.06 |
[백준] 1018번: 체스판 다시 칠하기_JAVA (0) | 2023.02.06 |
[백준] 9251번: LCS_JAVA (0) | 2023.01.25 |