목차
문제 정보
https://www.acmicpc.net/problem/14397
14397번: 해변
단위 정육각형 이루어져 있는 지도가 주어졌을 때, 해변의 길이를 구하는 프로그램을 작성하시오. 해변은 정육각형의 변 중에서 한 쪽은 물인데, 한 쪽은 땅인 곳을 의미한다.
www.acmicpc.net
난이도 : Silver 4
유형 : BFS, 그래프 탐색
문제 풀이
사각형을 다루는 일반적인 인접행렬과 달리 이 문제는 '육각형'이다.
그러므로 이동하는 방향이 6가지이며 또한 홀수, 짝수 줄마다 이동하는 방향이 다르다.
( 육각형들이 붙어 있지 않고 상하좌우로 정렬되어 있다고 생각해 보자)
홀수줄 : (-1,-1), (-1,0), (0,1),
그림처럼 짝수, 홀수줄마다 이동하는 방향이 다르다는 것을 알 수 있다.
기존 BFS 로직에 6가지 방향을 짝수, 홀수타입으로 나누고
현재 탐색하고 있는 육각형의 줄 위치가 짝수인지 홀수인지 판별하여 탐색하면 된다.
또한 탐색하고 있는 육지에서 다음 탐색하는 곳이 해변이면 결괏값을 1씩 증가시키면 되고
육지라면 다시 큐에 넣어서 계속 진행하면 된다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
/* author : DDing77 */
public class Main {
private final int[][] dirOdd = {{-1, -1}, {-1, 0}, {0, 1}, {1, 0}, {1, -1}, {0, -1}};
private final int[][] dirEven = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {0, -1}};
private int N;
private int M;
private char[][] map;
private boolean[][] isVisited;
private int res;
public void bfs(int x, int y) {
Queue<Integer> que = new LinkedList<>();
que.add(x);
que.add(y);
isVisited[x][y] = true;
while (!que.isEmpty()) {
int curX = que.poll();
int curY = que.poll();
for (int k = 0; k < 6; k++) {
int nX;
int nY;
if ((curX + 1) % 2 == 1) {
nX = curX + dirOdd[k][0];
nY = curY + dirOdd[k][1];
} else {
nX = curX + dirEven[k][0];
nY = curY + dirEven[k][1];
}
if (nX < 0 || nX >= N || nY < 0 || nY >= M) {
continue;
}
if (map[nX][nY] == '.') {
res++;
continue;
}
if (isVisited[nX][nY]) {
continue;
}
que.add(nX);
que.add(nY);
isVisited[nX][nY] = true;
}
}
}
public void solution() 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());
map = new char[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
map[i] = st.nextToken().toCharArray();
}
isVisited = new boolean[N][M];
res = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (!isVisited[i][j] && map[i][j] == '#') {
bfs(i, j);
}
}
}
System.out.println(res);
}
public static void main(String[] args) throws IOException {
new Main().solution();
}
}
'Algorithm, Problem Solving > 백준(boj)' 카테고리의 다른 글
[백준][Java] 12524 - Twibet (Large) (0) | 2023.10.10 |
---|---|
[백준][Java] 5081 - Constellations (0) | 2023.04.28 |
[백준][Java] 7562 - 나이트의 이동 (0) | 2023.04.03 |
[백준][Java] 14728 - 벼락치기 (0) | 2023.04.01 |
[백준][Java] 6186 - Best Grass (0) | 2023.03.31 |
댓글