[백준 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개의 댓글

관련 채용 정보