

구현 문제로, 그래프 탐색을 할 때는 DFS를 이용했다
풀이과정은 다음과 같다.
dx, dy를 시계방향으로 90도씩 설정(방향 바꿀 때 사용)
이동방향인 d 방향으로 주사위의 현위치 이동
👉 이동하는 곳이 지도를 벗어나면 반대 방향으로 d를 설정해 이동
DFS를 사용해 현재 칸의 B와 같은 값의 길을 탐색해 C 구하기
B와 C 곱해 점수에 더하기
A 구하기
👉 각 방향으로 이동 시 주사위의 값 변경을 4*3배열로 세팅

A와 B 비교해 다음 이동 방향 구하기
👉 A > B 일 때 d+1
👉 A < B 일 때 d-1
👉 A = B 일 때 d 그대로
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N, M, K, cx, cy, d, B, C, score, result, tcx, tcy;
static int[][] map;
static int[] dx = {0, 1, 0, -1}; // 동, 남, 서, 북
static int[] dy = {1, 0, -1, 0}; // 동, 남, 서, 북
static boolean[][] visited;
static int[][] dice;
public static void main(String[] args) 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());
K = Integer.parseInt(st.nextToken());
cx = 0; // 현재 x좌표
cy = 0; // 현재 y좌표
d = 0; // 방향(시작은 0(동쪽)방향으로)
tcx = 0; // 임시 현재 x좌표
tcy = 0; // 임시 현재 y좌표
result = 0;
map = new int[N][M];
dice = new int[4][3];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
dice[0][1] = 2;
dice[1][0] = 4;
dice[1][1] = 1;
dice[1][2] = 3;
dice[2][1] = 5;
dice[3][1] = 6;
for (int i = 0; i < K; i++) {
int ii = i + 1;
move();
}
System.out.println(result);
}
static void move() {
curLocation(); // 주사위 이동(cx, cy 설정)
setScore(cx, cy); // C 구해 점수 계산
result += score;
setDirection(); // 다음 방향 세팅
}
static void curLocation() {
tcx = dx[d] + cx;
tcy = dy[d] + cy;
if (tcx >= N || tcy >= M || tcx < 0 || tcy < 0) { // 길이 없으면 반대방향으로
switch (d) {
case 0:
d = 2;
break;
case 1:
d = 3;
break;
case 2:
d = 0;
break;
case 3:
d = 1;
break;
}
}
cx += dx[d];
cy += dy[d];
}
static void setScore(int cx, int cy) {
visited = new boolean[N][M];
B = map[cx][cy];
C = 0;
dfs(cx, cy); // C 개수를 세기 위해 현재 위치 주변에서 갈 수 있는 칸 탐색
if (C == 0)
C = 1;
score = C * B;
}
static void dfs(int cx, int cy) {
for (int i = 0; i < 4; i++) {
int nx = dx[i] + cx;
int ny = dy[i] + cy;
if (nx < N && ny < M && nx >= 0 && ny >= 0 && map[nx][ny] == B && !visited[nx][ny]) {
visited[nx][ny] = true;
C++;
dfs(nx, ny);
}
}
}
static void setDirection() {
setA(); // 이동한 방향대로 주사위 셋팅
// A와 B 비교해 다음 이동 방향 세팅
int A = dice[3][1];
if (A > B) {
if (d == 3)
d = 0;
else
d += 1;
} else if (A < B) {
if (d == 0)
d = 3;
else
d -= 1;
}
}
static void setA() {
switch (d) {
case 0: // 동쪽 이동 시
int tmp0 = dice[1][2];
dice[1][2] = dice[1][1];
dice[1][1] = dice[1][0];
dice[1][0] = dice[3][1];
dice[3][1] = tmp0;
break;
case 1: // 남쪽 이동 시
int tmp1 = dice[0][1];
dice[0][1] = dice[3][1];
dice[3][1] = dice[2][1];
dice[2][1] = dice[1][1];
dice[1][1] = tmp1;
break;
case 2: // 서쪽 이동 시
int tmp2 = dice[1][2];
dice[1][2] = dice[3][1];
dice[3][1] = dice[1][0];
dice[1][0] = dice[1][1];
dice[1][1] = tmp2;
break;
case 3: // 북쪽 이동 시
int tmp3 = dice[0][1];
dice[0][1] = dice[1][1];
dice[1][1] = dice[2][1];
dice[2][1] = dice[3][1];
dice[3][1] = tmp3;
break;
}
}
}
