[백준] 5373. 큐빙



문제

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





풀이

진짜 다시는 풀기 싫은 문제다. 괜히 코드 줄 수 좀 줄여보려고 합쳤다가 대체 어디서 틀렸는지 몰라서 하루종일 해매고 결국 하드 코딩으로 간신히 맞췄다. 겉보기에는 간단한 시뮬레이션 문제 같은데, 자세히 뜯어보면 조건이 상당히 많다. 일단 돌리는 방법만 해도 12가지에, 각 면이 돌아가는 경우가 각각 4가지며, 배열로 묶어서 풀 때 돌아가는 부분이 행인지, 열인지도 판단해줘야한다. 입력은 단순히 char형으로 입력받으면 되고, 이렇게 조건이 많고 복잡한 문제는 가급적 하드 코딩으로 해결하자. 그리고 꼭 종이에 써서 풀자! 머리로 하루종일 끙끙 대봤자 종이에 한번 쓰는 것보다 못한다.

참고로 문제가 문제다보니 반례 만들기가 정말 힘든데, 개인적으로 크게 도움이 된 사이트가 있다.
https://rubiks-cube-solver.com/#
직접 돌려서 확인해보자.

설명은... 솔직히 필요 없을 것 같다. 사실 조건을 빼먹었거나, 루미큐브를 돌리는 방식 등을 잘못해서 틀릴 뿐이지 뭔가 특별한 테크닉 같은 건 전혀 없다. 그냥 300줄 가량 모든 조건을 다 적어넣자.
삼성 SW 역량 테스트 문제라는데, 대체 이걸 어떻게 3시간 만에 풀 수 있는지 놀랍다.




//
//  5373.cpp
//  BJ
//
//  Created by 신기열 on 30/10/2019.
//  Copyright © 2019 신기열. All rights reserved.
//

#include <stdio.h>
#include <iostream>

using namespace std;

char cube[6][3][3];
char ans[1000][3][3];

void tUD(char d, char dir){
    char tmp[6][3][3];
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                tmp[i][j][k] = cube[i][j][k];
            }
        }
    }
    if(d == 'U'){
        if(dir == '+'){
            for(int i = 0; i < 3; i++){
                tmp[3][0][i] = cube[4][0][i]; tmp[4][0][i] = cube[2][0][i];
                tmp[5][0][i] = cube[3][0][i]; tmp[2][0][i] = cube[5][0][i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[0][k][2 - j] = cube[0][j][k];
                }
            }
        }
        else if(dir == '-'){
            for(int i = 0; i < 3; i++){
                tmp[3][0][i] = cube[5][0][i]; tmp[4][0][i] = cube[3][0][i];
                tmp[5][0][i] = cube[2][0][i]; tmp[2][0][i] = cube[4][0][i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[0][2 - k][j] = cube[0][j][k];
                }
            }
        }
    }
    else if(d == 'D'){
        if(dir == '+'){
            for(int i = 0; i < 3; i++){
                tmp[3][2][i] = cube[5][2][i]; tmp[4][2][i] = cube[3][2][i];
                tmp[5][2][i] = cube[2][2][i]; tmp[2][2][i] = cube[4][2][i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[1][k][2 - j] = cube[1][j][k];
                }
            }
        }
        else if(dir == '-'){
            for(int i = 0; i < 3; i++){
                tmp[3][2][i] = cube[4][2][i]; tmp[4][2][i] = cube[2][2][i];
                tmp[5][2][i] = cube[3][2][i]; tmp[2][2][i] = cube[5][2][i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[1][2 - k][j] = cube[1][j][k];
                }
            }
        }
    }
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                cube[i][j][k] = tmp[i][j][k];
            }
        }
    }
}
void tLR(char d, char dir){
    char tmp[6][3][3];
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                tmp[i][j][k] = cube[i][j][k];
            }
        }
    }
    if(d == 'L'){
        if(dir == '+'){
            for(int i = 0; i < 3; i++){
                tmp[3][i][2] = cube[1][2 - i][0]; tmp[0][i][0] = cube[3][2 - i][2];
                tmp[2][i][0] = cube[0][i][0]; tmp[1][i][0] = cube[2][i][0];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[4][k][2 - j] = cube[4][j][k];
                }
            }
        }
        else if(dir == '-'){
            for(int i = 0; i < 3; i++){
                tmp[3][i][2] = cube[0][2 - i][0]; tmp[0][i][0] = cube[2][i][0];
                tmp[2][i][0] = cube[1][i][0]; tmp[1][i][0] = cube[3][2 - i][2];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[4][2 - k][j] = cube[4][j][k];
                }
            }
        }
    }
    else if(d == 'R'){
        if(dir == '+'){
            for(int i = 0; i < 3; i++){
                tmp[3][i][0] = cube[0][2 - i][2]; tmp[2][i][2] = cube[1][i][2];
                tmp[1][i][2] = cube[3][2 - i][0]; tmp[0][i][2] = cube[2][i][2];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[5][k][2 - j] = cube[5][j][k];
                }
            }
        }
        else if(dir == '-'){
            for(int i = 0; i < 3; i++){
                tmp[3][i][0] = cube[1][2 - i][2]; tmp[0][i][2] = cube[3][2 - i][0];
                tmp[2][i][2] = cube[0][i][2]; tmp[1][i][2] = cube[2][i][2];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[5][2 - k][j] = cube[5][j][k];
                }
            }
        }
    }
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                cube[i][j][k] = tmp[i][j][k];
            }
        }
    }
}

void tFB(char d, char dir){
    char tmp[6][3][3];
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                tmp[i][j][k] = cube[i][j][k];
            }
        }
    }
    if(d == 'F'){
        if(dir == '+'){
            for(int i = 0; i < 3; i++){
                tmp[0][2][i] = cube[4][2 - i][2]; tmp[5][i][0] = cube[0][2][i];
                tmp[1][0][i] = cube[5][2 - i][0]; tmp[4][i][2] = cube[1][0][i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[2][k][2 - j] = cube[2][j][k];
                }
            }
        }
        else if(dir == '-'){
            for(int i = 0; i < 3; i++){
                tmp[0][2][i] = cube[5][i][0]; tmp[4][i][2] = cube[0][2][2 - i];
                tmp[1][0][i] = cube[4][i][2]; tmp[5][i][0] = cube[1][0][2 - i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[2][2 - k][j] = cube[2][j][k];
                }
            }
        }
    }
    else if(d == 'B'){
        if(dir == '+'){
            for(int i = 0; i < 3; i++){
                tmp[0][0][i] = cube[5][i][2]; tmp[4][i][0] = cube[0][0][2 - i];
                tmp[1][2][i] = cube[4][i][0]; tmp[5][i][2] = cube[1][2][2 - i];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[3][k][2 - j] = cube[3][j][k];
                }
            }
        }
        else if(dir == '-'){
            for(int i = 0; i < 3; i++){
                tmp[5][i][2] = cube[0][0][i]; tmp[1][2][i] = cube[5][2 - i][2];
                tmp[4][i][0] = cube[1][2][i]; tmp[0][0][i] = cube[4][2 - i][0];
            }
            for(int j = 0; j < 3; j++){
                for(int k = 0; k < 3; k++){
                    tmp[3][2 - k][j] = cube[3][j][k];
                }
            }
        }
    }
    for(int i = 0; i < 6; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                cube[i][j][k] = tmp[i][j][k];
            }
        }
    }
}

void init(){
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            cube[0][i][j] = 'w'; cube[1][i][j] = 'y'; cube[2][i][j] = 'r';
            cube[3][i][j] = 'o'; cube[4][i][j] = 'g'; cube[5][i][j] = 'b';
        }
    }
}

int main(){
    init();
    
    int n; cin >> n;
    for(int i = 0; i < n; i++){
        int m; cin >> m; char d[m]; char dir[m];
        for(int j = 0; j < m; j++){
            cin >> d[j] >> dir[j];
        }
        for(int j = 0; j < m; j++){
            if((d[j] == 'U' && dir[j] == '+') || (d[j] == 'U' && dir[j] == '-') ||
               (d[j] == 'D' && dir[j] == '+') || (d[j] == 'D' && dir[j] == '-')){
                tUD(d[j], dir[j]);
            }
            else if((d[j] == 'L' && dir[j] == '+') || (d[j] == 'L' && dir[j] == '-') ||
                    (d[j] == 'R' && dir[j] == '+') || (d[j] == 'R' && dir[j] == '-')){
                tLR(d[j], dir[j]);
            }
            else if((d[j] == 'F' && dir[j] == '+') || (d[j] == 'F' && dir[j] == '-') ||
                    (d[j] == 'B' && dir[j] == '+') || (d[j] == 'B' && dir[j] == '-')){
                tFB(d[j], dir[j]);
            }
            }
        }
        for(int p = 0; p < 3; p++){
            for(int q = 0; q < 3; q++){
                ans[i][p][q] =  cube[0][p][q];
            }
        }
        init();
    }
    for(int i = 0; i < n; i++){
        for(int p = 0; p < 3; p++){
            for(int q = 0; q < 3; q++){
                cout << ans[i][p][q];
            }
            cout << '\n';
        }
    }

    return 0;
}


깃허브에 위, 아래, 앞, 뒤, 좌, 우의 면의 상태를 체크할 수 있는 출력을 주석 처리해서 넣어놨다. (여기에 적으려니까 너무 많아져서 짤려서 나온다..) 혹시 필요하다면 보고 확인해보자.

소스코드 : https://github.com/betterafter/problem-solving/blob/main/baekjoon/5373.cpp

댓글