문제 출처

1. 문제설명


  • 우리가 흔히 알고 있는 3x3 크기의 큐브가 있다.
  • 큐브는 6가지 면이 각각 다른 색을 갖게 된다.
  • 큐브를 돌리는 순서와 방향이 주어지는데, 이때마다 가장 윗면의 색상을 구하라



2. 알고리즘 설계


  • 극한의 시뮬레이션 문제이다.
  • 이전에 풀었던 주사위 문제와 유사한데 이 문제는 차원이 추가되었다.
  • 머리로 상상하면서 푸는 게 너무 힘들어서 직접 큐브를 두고 풀었다…
  • 위 또는 아래 면을 회전시킬 때는 인덱스로 값을 갱신시키면 되지만,
  • 앞, 뒤, 좌, 우를 갱신시킬 때
    • 변경에 필요한 값을 지닌 인덱스, 변경할 위치의 인덱스가 서로 반대라서
    • 코드가 조금 지저분해진다.
  • 시뮬레이션 문제라서, 로직을 차지하는 부분이 없다.
    • include문 뒤에 2차원 배열을 회전시키는 로직은 자주 쓰이니 꼭 알아두자



3. 전체 코드


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<vector<char>> rotateRight(vector<vector<char>> cube){
    vector<vector<char>> tmp(3, vector<char>(3, ' '));

    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            tmp[j][3 - i - 1] = cube[i][j];
        }
    }
    
    return tmp;
}

vector<vector<char>> rotateLeft(vector<vector<char>> cube){
    vector<vector<char>> tmp(3, vector<char>(3, ' '));

    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            tmp[3 - j - 1][i] = cube[i][j];
        }
    }
    
    return tmp;
}

int main(void){
    int n;
    cin >> n;

    for(int i = 0; i < n; i++){
        int t;
        vector<string> v;
        vector<vector<char>> up(3, vector<char>(3, 'w'));
        vector<vector<char>> down(3, vector<char>(3, 'y'));
        vector<vector<char>> front(3, vector<char>(3, 'r'));
        vector<vector<char>> back(3, vector<char>(3, 'o'));
        vector<vector<char>> left(3, vector<char>(3, 'g'));
        vector<vector<char>> right(3, vector<char>(3, 'b'));

        cin >> t;

        for(int j = 0; j < t; j++){
            string s;
            
            cin >> s;
            v.push_back(s);
        }

        for(int j = 0; j < v.size(); j++){
            vector<char> tmp;

            switch(v[j][0]){
                case 'U':
                    if(v[j][1] == '-'){
                        tmp = right[0];
                        right[0] = front[0];
                        front[0] = left[0];
                        left[0] = back[0];
                        back[0] = tmp;
                        up = rotateLeft(up);
                    }
                    else{
                        tmp = left[0];
                        left[0] = front[0];
                        front[0] = right[0];
                        right[0] = back[0];
                        back[0] = tmp;
                        up = rotateRight(up);
                    }
                    break;
                case 'D':
                    if(v[j][1] == '-'){
                        tmp = right[2];
                        right[2] = back[2];
                        back[2] = left[2];
                        left[2] = front[2];
                        front[2] = tmp;
                        down = rotateLeft(down);
                    }
                    else{
                        tmp = left[2];
                        left[2] = back[2];
                        back[2] = right[2];
                        right[2] = front[2];
                        front[2] = tmp;
                        down = rotateRight(down);
                    }
                    break;
                case 'F':
                    if(v[j][1] == '-'){
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(right[k][0]);
                        }

                        for(int k = 0; k < 3; k++){
                            right[k][0] = down[0][2 - k];
                            down[0][2 - k] = left[2 - k][2];
                            left[2 - k][2] = up[2][k];
                            up[2][k] = tmp[k];
                        }
                        front = rotateLeft(front);
                    }
                    else{
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(left[k][2]);
                        }
                        
                        for(int k = 0; k < 3; k++){
                            left[k][2] = down[0][k];
                            down[0][k] = right[2 - k][0];
                            right[2 - k][0] = up[2][2 - k];
                            up[2][2 - k] = tmp[k];
                        }
                        front = rotateRight(front);
                    }
                    break;
                case 'B':
                    if(v[j][1] == '-'){
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(left[k][0]);
                        }

                        for(int k = 0; k < 3; k++){
                            left[k][0] = down[2][k];
                            down[2][k] = right[2 - k][2];
                            right[2 - k][2] = up[0][2 - k];
                            up[0][2 - k] = tmp[k];
                        }
                        back = rotateLeft(back);
                    }
                    else{
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(right[k][2]);
                        }

                        for(int k = 0; k < 3; k++){
                            right[k][2] = down[2][2 - k];
                            down[2][2 - k] = left[2 - k][0];
                            left[2 - k][0] = up[0][k];
                            up[0][k] = tmp[k];
                        }
                        back = rotateRight(back);
                    }
                    break;
                case 'L':
                    if(v[j][1] == '-'){
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(front[k][0]);
                        }

                        for(int k = 0; k < 3; k++){
                            front[k][0] = down[k][0];
                            down[k][0] = back[2 - k][2];
                            back[2 - k][2] = up[k][0];
                            up[k][0] = tmp[k];
                        }
                        left = rotateLeft(left);
                    }
                    else{
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(back[k][2]);
                        }

                        for(int k = 0; k < 3; k++){
                            back[k][2] = down[2 - k][0];
                            down[2 - k][0] = front[2 - k][0];
                            front[2 - k][0] = up[2 - k][0];
                            up[2 - k][0] = tmp[k];
                        }
                        left = rotateRight(left);
                    }
                    break;
                case 'R':
                    if(v[j][1] == '-'){
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(back[k][0]);
                        }

                        for(int k = 0; k < 3; k++){
                            back[k][0] = down[2 - k][2];
                            down[2 - k][2] = front[2 - k][2];
                            front[2 - k][2] = up[2 - k][2];
                            up[2 - k][2] = tmp[k];
                        }
                        right = rotateLeft(right);
                    }
                    else{
                        for(int k = 0; k < 3; k++){
                            tmp.push_back(front[k][2]);
                        }

                        for(int k = 0; k < 3; k++){
                            front[k][2] = down[k][2];
                            down[k][2] = back[2 - k][0];
                            back[2 - k][0] = up[k][2];
                            up[k][2] = tmp[k];
                        }
                        right = rotateRight(right);
                    }
                    break;
            }
        }

        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                cout << up[j][k];
            }
            cout << endl;
        }
    }
    
    return 0;
}



4. 소감


  • 문제를 풀고 난 후 깨닫게 되었는데,
  • 생각해보니, 시계방향 또는 반시계방향을 3번 돌리면 그 반대 방향이 된다.
  • 따라서, 한번의 구현으로 1번, 3번을 실행시키면, 해당 방향과 반대 방향 구현이 가능하다.