[백준 14499] 주사위 굴리기(Java)

최민길(Gale)·2023년 1월 19일
1

알고리즘

목록 보기
17/172

문제 링크 : https://www.acmicpc.net/problem/14499

이 문제는 문제에 나온 조건을 하나하나 구현하면 쉽게 풀 수 있습니다.

이 문제의 가장 핵심은 주사위를 굴리는 방법입니다. 주사위를 각 방향대로 굴렸을 때 가장 위와 가장 아래에 어떤 수가 존재할 지를 계산하는 것이 이 문제의 포인트입니다. 이는 전개도를 이용해서 생각해보면 쉽게 해결할 수 있습니다.

문제에 나와 있는 전개도를 기준으로 생각해보겠습니다. 이 경우 주사위를 다음과 같이 생각할 수 있습니다.

  • 앞면 : 2
  • 윗면 : 1
  • 뒷면 : 5
  • 아랫면 : 6
  • 왼쪽면 : 4
  • 오른쪽면 : 3

이 때, 상하로 움직이는 경우 왼쪽면과 오른쪽면은 변하지 않고 나머지 숫자들만 변하는 것을 알 수 있습니다. 또한 좌우로 움직이는 경우 왼쪽면 - 윗면 - 오른쪽면 - 아랫면 이 4면의 수가 변하는 것을 알 수 있습니다. 따라서 이 부분을 염두에 두고 움직이는 방향대로 전개도의 각 면의 값이 바뀌는 규칙성을 대입하여 문제를 풀면 됩니다.

다음은 코드입니다.

import java.util.*;
import java.io.*;

public class Main{
    static int N,M,x,y,K;
    static int[][] req = new int[21][21];
    static Queue<Integer> cmds = new LinkedList<>();
    static Dice dice = new Dice();

    public static void main(String[] args) throws Exception{
        input();

        StringBuilder sb = new StringBuilder();
        while(!cmds.isEmpty()){
            int cmd = cmds.poll();
            int top = getDiceTop(cmd);
            if(top!=-1){
                sb.append(top);
                sb.append("\n");
            }
        }
        System.out.println(sb);
    }

    static int getDiceTop(int cmd){
        switch (cmd){
            case 1:
                if(x+1<M){
                    // 주사위를 굴렸을 때
                    dice.moveEast();
                    x++;
                    // 이동한 칸에 쓰여 있는 수가 0이면
                    // 주사위의 바닥면에 쓰여 있는 수가 칸에 복사됨
                    if(req[y][x]==0) dice.copyToMap(req,y,x);
                    // 0이 아닌 경우
                    else{
                        // 칸에 쓰여 있는 수가 주사위 바닥면으로 복사
                        dice.copyToDice(req[y][x]);
                        // 칸에 쓰여 있는 수는 0
                        req[y][x] = 0;
                    }
                    // 지도의 안에 있는 경우에만 명령 수행
                    return dice.print();
                }
                break;
            case 2:
                if(x-1>=0){
                    dice.moveWest();
                    x--;
                    if(req[y][x]==0) dice.copyToMap(req,y,x);
                    else{
                        dice.copyToDice(req[y][x]);
                        req[y][x] = 0;
                    }
                    return dice.print();
                }
                break;
            case 3:
                if(y-1>=0){
                    dice.moveNorth();
                    y--;
                    if(req[y][x]==0) dice.copyToMap(req,y,x);
                    else{
                        dice.copyToDice(req[y][x]);
                        req[y][x] = 0;
                    }
                    return dice.print();
                }
                break;
            case 4:
                if(y+1<N){
                    dice.moveSouth();
                    y++;
                    if(req[y][x]==0) dice.copyToMap(req,y,x);
                    else{
                        dice.copyToDice(req[y][x]);
                        req[y][x] = 0;
                    }
                    return dice.print();
                }
                break;
        }
        return -1;
    }

    static void input() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        y = Integer.parseInt(st.nextToken());
        x = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        for(int i=0;i<N;i++){
            st = new StringTokenizer(br.readLine());
            for(int j=0;j<M;j++){
                req[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        st = new StringTokenizer(br.readLine());
        for(int i=0;i<K;i++){
            cmds.add(Integer.parseInt(st.nextToken()));
        }
    }
}

class Dice{
    int front;
    int back;
    int up;
    int down;
    int left;
    int right;

    public Dice(){
        this.front = 0;
        this.back = 0;
        this.up = 0;
        this.down=0;
        this.left = 0;
        this.right = 0;
    }

    public void moveNorth(){
        int tmp = this.front;
        this.front = this.up;
        this.up = this.back;
        this.back = this.down;
        this.down = tmp;
    }

    public void moveSouth(){
        int tmp = this.down;
        this.down = this.back;
        this.back = this.up;
        this.up = this.front;
        this.front = tmp;
    }

    public void moveEast(){
        int tmp = this.down;
        this.down = this.right;
        this.right = this.up;
        this.up = this.left;
        this.left = tmp;
    }

    public void moveWest(){
        int tmp = this.down;
        this.down = this.left;
        this.left = this.up;
        this.up = this.right;
        this.right = tmp;
    }

    public int print(){return up;}
    public void copyToDice(int req){this.down = req;}
    public void copyToMap(int[][] req, int y, int x){req[y][x] = this.down;}
}

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글