[백준 | Java] 23288 주사위 굴리기 2

알린·2024년 4월 8일

baekjoon

목록 보기
49/68

내 풀이

구현 문제로, 그래프 탐색을 할 때는 DFS를 이용했다
풀이과정은 다음과 같다.

  1. dx, dy를 시계방향으로 90도씩 설정(방향 바꿀 때 사용)

  2. 이동방향인 d 방향으로 주사위의 현위치 이동
    👉 이동하는 곳이 지도를 벗어나면 반대 방향으로 d를 설정해 이동

  3. DFS를 사용해 현재 칸의 B와 같은 값의 길을 탐색해 C 구하기

  4. B와 C 곱해 점수에 더하기

  5. A 구하기
    👉 각 방향으로 이동 시 주사위의 값 변경을 4*3배열로 세팅

  6. 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;
        }
    }
}

profile
짱이 되고싶은 개발 기록

0개의 댓글