[BaekJoon] 23288 주사위 굴리기 2 (Java)

오태호·2023년 3월 30일
0

백준 알고리즘

목록 보기
187/395
post-thumbnail

1.  문제 링크

https://www.acmicpc.net/problem/23288

2.  문제







요약

  • 명우기업은 택배 화물을 모아서 처리하는 집하장을 몇 개 마련했지만, 택배 화물이 각 집하장들 사이를 오갈 때 어떤 경로를 거쳐야 하는지 결정하지 못했습니다.
  • 집하장들 사이의 경로와 해당 경로로 이동할 때 필요한 시간이 주어질 때, 경로표를 구하는 문제입니다.
  • 입력: 첫 번째 줄에 200보다 작거나 같은 자연수인 집하장의 개수 n과 10,000보다 작거나 같은 자연수인 집하장간 경로의 개수 m이 주어지고 두 번째 줄부터 m개의 줄에 집하장간 경로가 주어집니다. 각 경로에서는 두 집하장의 번호와 그 사이를 오가는데 필요한 시간이 주어집니다.
    • 집하장의 번호들과 경로의 소요시간은 모두 1,000 이하의 자연수입니다.
  • 출력: 위의 예시와 같은 형식으로 경로표를 출력합니다.

3.  소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    final static int[] pairs = new int[] {0, 6, 5, 4, 3, 2, 1};
    // 0 : 동, 1 : 서, 2 : 남, 3 : 북
    final static int[] rotateCW = {2, 3, 1, 0}, rotateCCW = {3, 2, 0, 1}, reverseDirection = {1, 0, 3, 2};
    final static int[][] moveAmount = {
            {0, 1},
            {0, -1},
            {1, 0},
            {-1, 0}
    };

    static int N, M, K;
    static int[][] map;
    static int[][] dice = {
            {0, 2, 0},
            {4, 1, 3},
            {0, 5, 0},
            {0, 6, 0}
    };
    static Dice diceLoc = new Dice(0, 0, 0);
    static int[] dx = {-1, 0, 1, 0}, dy = {0, -1, 0, 1};

    static void input() {
        Reader scanner = new Reader();

        N = scanner.nextInt();
        M = scanner.nextInt();
        K = scanner.nextInt();
        map = new int[N][M];

        for(int row = 0; row < N; row++) {
            for(int col = 0; col < M; col++)
                map[row][col] = scanner.nextInt();
        }
    }

    static void solution() {
        int sum = 0;
        for(int count = 0; count < K; count++)
            sum += oneTurn();

        System.out.println(sum);
    }

    static int oneTurn() {
        move();
        int point = bfs(diceLoc.x, diceLoc.y);
        setDirection();

        return point;
    }

    static void setDirection() {
        if(dice[3][1] > map[diceLoc.x][diceLoc.y]) {
            diceLoc.direction = rotateCW[diceLoc.direction];
        } else if(dice[3][1] < map[diceLoc.x][diceLoc.y]) {
            diceLoc.direction = rotateCCW[diceLoc.direction];
        }
    }

    static int bfs(int x, int y) {
        Queue<int[]> queue = new LinkedList<>();
        boolean[][] visited = new boolean[N][M];
        int num = map[x][y], count = 1;

        queue.offer(new int[] {x, y});
        visited[x][y] = true;

        while(!queue.isEmpty()) {
            int[] cur = queue.poll();

            for(int dir = 0; dir < 4; dir++) {
                int cx = cur[0] + dx[dir], cy = cur[1] + dy[dir];

                if(isInMap(cx, cy) && map[cx][cy] == num && !visited[cx][cy]) {
                    visited[cx][cy] = true;
                    count++;
                    queue.offer(new int[] {cx, cy});
                }
            }
        }

        return num * count;
    }

    static void move() {
        int x = diceLoc.x + moveAmount[diceLoc.direction][0], y = diceLoc.y + moveAmount[diceLoc.direction][1];

        if(!isInMap(x, y)) diceLoc.direction = reverseDirection[diceLoc.direction];
        diceLoc.x += moveAmount[diceLoc.direction][0]; diceLoc.y += moveAmount[diceLoc.direction][1];

        if(diceLoc.direction == 0) moveEast();
        else if(diceLoc.direction == 1) moveWest();
        else if(diceLoc.direction == 2) moveSouth();
        else if(diceLoc.direction == 3) moveNorth();
    }

    static void moveEast() {
        dice[1][2] = dice[1][1];
        dice[1][1] = dice[1][0];

        dice[3][1] = pairs[dice[1][1]];
        dice[1][0] = pairs[dice[1][2]];
    }

    static void moveWest() {
        dice[1][0] = dice[1][1];
        dice[1][1] = dice[1][2];

        dice[3][1] = pairs[dice[1][1]];
        dice[1][2] = pairs[dice[1][0]];
    }

    static void moveSouth() {
        int temp = dice[3][1];

        for(int idx = 2; idx >= 0; idx--)
            dice[idx + 1][1] = dice[idx][1];

        dice[0][1] = temp;
    }

    static void moveNorth() {
        int temp = dice[0][1];

        for(int idx = 1; idx <= 3; idx++)
            dice[idx - 1][1] = dice[idx][1];

        dice[3][1] = temp;
    }

    static boolean isInMap(int x, int y) {
        if(x >= 0 && x < N && y >= 0 && y < M) return true;
        return false;
    }

    static class Dice {
        int x, y, direction;

        public Dice(int x, int y, int direction) {
            this.x = x;
            this.y = y;
            this.direction = direction;
        }
    }

    public static void main(String[] args) {
        input();
        solution();
    }

    static class Reader {
        BufferedReader br;
        StringTokenizer st;

        public Reader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while(st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }
    }
}
profile
자바, 웹 개발을 열심히 공부하고 있습니다!

0개의 댓글