
격자의 행 방향에 따라 이동 방향이 다르기 때문에 이를 고려해줘야한다.
짝수 행
짝수 번째 행에서는 각 칸이 왼쪽 대각선과 오른쪽 대각선 방향이 다른 방식으로 배치된다. 예를 들어 행이 짝수인 경우에는 대각선 위로 올라가는 방향이 (-1, -1)이고, 대각선 아래로 내려가는 방향은 (-1, 0)과 같은 형태이다. 이렇게 되면 격자에서 대각선이 기울어진 모양처럼 배열된다.
Even = {-1, 0, -1, 1, -1, 0}:
이 배열은 짝수 행에서 각 칸이 이동할 수 있는 6개의 방향을 정의한다.
방향은 왼쪽 상단, 상, 오른쪽 상단, 왼쪽 하단, 하, 오른쪽 하단을 포함한다.홀수 행 (dyOdd)
홀수 번째 행에서는 각 칸이 왼쪽 대각선과 오른쪽 대각선 방향이 다르게 배치된다. 즉 대각선이 다른 방향으로 기울어지기 때문에 짝수 행과는 다르게 계산해야 한다.
Odd = {0, 1, -1, 1, 0, 1}:
이 배열은 홀수 행에서 각 칸이 이동할 수 있는 6개의 방향을 정의한다.
여기서도 왼쪽 상단, 상, 오른쪽 상단, 왼쪽 하단, 하, 오른쪽 하단의 순서로 방향을 설정한다.
시간복잡도:O(N*M), 공간복잡도:O(N*M)
import java.util.*;
import java.io.*;
class Main {
static int[] dx = {-1, -1, 0, 0, 1, 1};
static int[] dyEven = {-1, 0, -1, 1, -1, 0}; // 짝수 행
static int[] dyOdd = {0, 1, -1, 1, 0, 1}; // 홀수 행
static char[][] arr;
static int length = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
arr = new char[n][m];
for(int i=0;i<n;i++){
String s = br.readLine();
for(int j=0;j<m;j++){
arr[i][j]=s.charAt(j);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(arr[i][j] == '.'){
countBeachLength(i, j, n, m);
}
}
}
System.out.println(length);
}
public static void countBeachLength(int x, int y, int n, int m){
int[] dy = (x % 2 == 0) ? dyEven : dyOdd;
for(int i=0; i<6;i++){
int xx = x + dx[i];
int yy = y + dy[i];
if (xx >= 0 && xx < n && yy >= 0 && yy < m && arr[xx][yy] == '#') {
length++;
}
}
}
}
