코드굽는 타자기

Baekjoon[5373] - 큐빙 본문

알고리즘/Simulation

Baekjoon[5373] - 큐빙

bright-jun 2020. 3. 2. 20:14

링크

 

5373번: 큐빙

문제 루빅스 큐브는 삼차원 퍼즐이다. 보통 루빅스 큐브는 3×3×3개의 작은 정육면체로 이루어져 있다. 퍼즐을 풀려면 각 면에 있는 아홉 개의 작은 정육면체의 색이 동일해야 한다. 큐브는 각 면을 양방향으로 90도 만큼 돌릴 수 있도록 만들어져 있다. 회전이 마친 이후에는, 다른 면을 돌릴 수 있다. 이렇게 큐브의 서로 다른 면을 돌리다 보면, 색을 섞을 수 있다. 이 문제에서는 루빅스 큐브가 모두 풀린 상태에서 시작한다. 윗 면은 흰색, 아랫 면은 노란

www.acmicpc.net

문제설명

이거보고 품, 마침 A형 기출에 있었음

  • 시뮬레이션

문제풀이

  • 빡구현, 그저 빡구현

문제코드

package baekjoon;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main5373 {

    public static char[][] U = new char[3][3];
    public static char[][] D = new char[3][3];
    public static char[][] F = new char[3][3];
    public static char[][] B = new char[3][3];
    public static char[][] L = new char[3][3];
    public static char[][] R = new char[3][3];

    public static void rotate(char[] oper) {
        boolean clockwise=true;

        switch (oper[1]) {
        case '+':
            clockwise=true;
            break;
        case '-':
            clockwise=false;
            break;
        }

        switch (oper[0]) {
        case 'U':
            front_rotate(U, clockwise);
            front_rotate(U, clockwise);
            side_rotate(B, R, F, L,
                    new int[][] {{0,2},{0,1},{0,0}},
                    new int[][] {{0,2},{0,1},{0,0}},
                    new int[][] {{0,2},{0,1},{0,0}},
                    new int[][] {{0,2},{0,1},{0,0}}, clockwise);
            break;
        case 'D':
            front_rotate(D, clockwise);
            front_rotate(D, clockwise);
            side_rotate(F, R, B, L,
                    new int[][] {{2,0},{2,1},{2,2}},
                    new int[][] {{2,0},{2,1},{2,2}},
                    new int[][] {{2,0},{2,1},{2,2}},
                    new int[][] {{2,0},{2,1},{2,2}}, clockwise);
            break;
        case 'F':
            front_rotate(F, clockwise);
            front_rotate(F, clockwise);
            side_rotate(U, R, D, L,
                    new int[][] {{2,0},{2,1},{2,2}},
                    new int[][] {{0,0},{1,0},{2,0}},
                    new int[][] {{0,2},{0,1},{0,0}},
                    new int[][] {{2,2},{1,2},{0,2}}, clockwise);
            break;
        case 'B':
            front_rotate(B, clockwise);
            front_rotate(B, clockwise);
            side_rotate(U, L, D, R,
                    new int[][] {{0,2},{0,1},{0,0}},
                    new int[][] {{0,0},{1,0},{2,0}},
                    new int[][] {{2,0},{2,1},{2,2}},
                    new int[][] {{2,2},{1,2},{0,2}}, clockwise);
            break;
        case 'L':
            front_rotate(L, clockwise);
            front_rotate(L, clockwise);
            side_rotate(U, F, D, B,
                    new int[][] {{0,0},{1,0},{2,0}},
                    new int[][] {{0,0},{1,0},{2,0}},
                    new int[][] {{0,0},{1,0},{2,0}},
                    new int[][] {{2,2},{1,2},{0,2}}, clockwise);
            break;
        case 'R':
            front_rotate(R, clockwise);
            front_rotate(R, clockwise);
            side_rotate(U, B, D, F,
                    new int[][] {{2,2},{1,2},{0,2}},
                    new int[][] {{0,0},{1,0},{2,0}},
                    new int[][] {{2,2},{1,2},{0,2}},
                    new int[][] {{2,2},{1,2},{0,2}}, clockwise);
            break;
        }
    }

    public static void front_rotate(char[][] target, boolean clockwise) {
        char temp;
//        시계방향
        if (clockwise) {
            temp = target[0][0];
            target[0][0] = target[1][0];
            target[1][0] = target[2][0];
            target[2][0] = target[2][1];
            target[2][1] = target[2][2];
            target[2][2] = target[1][2];
            target[1][2] = target[0][2];
            target[0][2] = target[0][1];
            target[0][1] = temp;
        }
//        반시계방향
        else {
            temp = target[0][0];
            target[0][0] = target[0][1];
            target[0][1] = target[0][2];
            target[0][2] = target[1][2];
            target[1][2] = target[2][2];
            target[2][2] = target[2][1];
            target[2][1] = target[2][0];
            target[2][0] = target[1][0];
            target[1][0] = temp;
        }
    }

    public static void side_rotate(char[][] target0, char[][] target1, char[][] target2, char[][] target3,
                                    int[][] idx0, int[][] idx1, int[][] idx2, int[][] idx3, 
                                    boolean clockwise) {
        char[] temp = new char[3];
//        시계방향
        if (clockwise) {
            temp[0] = target0[idx0[0][0]][idx0[0][1]];
            temp[1] = target0[idx0[1][0]][idx0[1][1]];
            temp[2] = target0[idx0[2][0]][idx0[2][1]];

            target0[idx0[0][0]][idx0[0][1]] = target3[idx3[0][0]][idx3[0][1]];
            target0[idx0[1][0]][idx0[1][1]] = target3[idx3[1][0]][idx3[1][1]];
            target0[idx0[2][0]][idx0[2][1]] = target3[idx3[2][0]][idx3[2][1]];

            target3[idx3[0][0]][idx3[0][1]] = target2[idx2[0][0]][idx2[0][1]];
            target3[idx3[1][0]][idx3[1][1]] = target2[idx2[1][0]][idx2[1][1]];
            target3[idx3[2][0]][idx3[2][1]] = target2[idx2[2][0]][idx2[2][1]];

            target2[idx2[0][0]][idx2[0][1]] = target1[idx1[0][0]][idx1[0][1]];
            target2[idx2[1][0]][idx2[1][1]] = target1[idx1[1][0]][idx1[1][1]];
            target2[idx2[2][0]][idx2[2][1]] = target1[idx1[2][0]][idx1[2][1]];

            target1[idx1[0][0]][idx1[0][1]] = temp[0];
            target1[idx1[1][0]][idx1[1][1]] = temp[1];
            target1[idx1[2][0]][idx1[2][1]] = temp[2];
        }
//        반시계방향
        else {
            temp[0] = target0[idx0[0][0]][idx0[0][1]];
            temp[1] = target0[idx0[1][0]][idx0[1][1]];
            temp[2] = target0[idx0[2][0]][idx0[2][1]];

            target0[idx0[0][0]][idx0[0][1]] = target1[idx1[0][0]][idx1[0][1]];
            target0[idx0[1][0]][idx0[1][1]] = target1[idx1[1][0]][idx1[1][1]];
            target0[idx0[2][0]][idx0[2][1]] = target1[idx1[2][0]][idx1[2][1]];

            target1[idx1[0][0]][idx1[0][1]] = target2[idx2[0][0]][idx2[0][1]];
            target1[idx1[1][0]][idx1[1][1]] = target2[idx2[1][0]][idx2[1][1]];
            target1[idx1[2][0]][idx1[2][1]] = target2[idx2[2][0]][idx2[2][1]];

            target2[idx2[0][0]][idx2[0][1]] = target3[idx3[0][0]][idx3[0][1]];
            target2[idx2[1][0]][idx2[1][1]] = target3[idx3[1][0]][idx3[1][1]];
            target2[idx2[2][0]][idx2[2][1]] = target3[idx3[2][0]][idx3[2][1]];

            target3[idx3[0][0]][idx3[0][1]] = temp[0];
            target3[idx3[1][0]][idx3[1][1]] = temp[1];
            target3[idx3[2][0]][idx3[2][1]] = temp[2];
        }
    }
    public static void main(String[] args) throws NumberFormatException, IOException {
        System.setIn(new FileInputStream("res/baekjoon/5373.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());


        for (int test_case = 0; test_case < T; test_case++) {

//            큐브 초기화
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    U[i][j] = 'w';
                    D[i][j] = 'y';
                    F[i][j] = 'r';
                    B[i][j] = 'o';
                    L[i][j] = 'g';
                    R[i][j] = 'b';
                }
            }

            int N = Integer.parseInt(br.readLine());
            st = new StringTokenizer(br.readLine());

            char[] oper;
            boolean clockwise=true;

////            디버깅
//            U = new char[][] {{'a','b','c'},{'a','b','c'},{'a','b','c'}};
//            D = new char[][] {{'b','c','d'},{'b','c','d'},{'b','c','d'}};
//            F = new char[][] {{'c','d','e'},{'c','d','e'},{'c','d','e'}};
//            B = new char[][] {{'d','e','f'},{'d','e','f'},{'d','e','f'}};
//            L = new char[][] {{'e','f','g'},{'e','f','g'},{'e','f','g'}};
//            R = new char[][] {{'f','g','h'},{'f','g','h'},{'f','g','h'}};
//            
//            rotate(new char[] {'U','+'});
//            rotate(new char[] {'U','-'});
//            rotate(new char[] {'D','+'});
//            rotate(new char[] {'D','-'});
//            rotate(new char[] {'F','+'});
//            rotate(new char[] {'F','-'});
//            rotate(new char[] {'B','+'});
//            rotate(new char[] {'B','-'});
//            rotate(new char[] {'L','+'});
//            rotate(new char[] {'L','-'});
//            rotate(new char[] {'R','+'});
//            rotate(new char[] {'R','-'});


            for (int o = 0; o < N; o++) {
                oper = st.nextToken().toCharArray();
                rotate(oper);
            }//end for oper

            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    System.out.print(U[i][j]);
                }
                System.out.println();
            }

        }
    }
}

아쉬운점

  • front_rotate 할 때 1칸만 이동하게 구했했어서 2번 돌림.
  • F, B 에서 index실수 많이함
    • 상하좌우 순서반전이있어서 좀 신경써야함
    • 머리에 쥐나겠음
  • 시간(2시간)

잘한점

  • 일단 꾸역꾸역 디버깅하면서 수정함
    • 디버깅용 큐브 면도 나름 규칙성있게 짰음
  • 회전하는 메서드 인덱스랑 배열 인자로 받아서 하도록 만듬.
Comments