[BOJ 5373] 큐빙
풀이
단순한 구현 문제이나 생각이 꼬이지 않으면서 구현을 잘 해주어야하는 문제이다.
총 6 면(위 아래 앞 뒤 좌 우)의 큐브가 각각 회전하면서 어떻게 되는지를 생각해야하는데, 큐브의 상태를 어떻게 정의하느냐에 따라 구현 난이도가 높아질 수 있다.
아래의 코드는 큐브의 면을 0,1,2,3,4,5 로 번호를 지정하고, 각 면에서 한 타일 당 좌상단부터 0~8 까지의 숫자를 부여한 상태이다.
이 상태에서 각각의 회전하는 경우에 따른 함수를 구현한 것이다.
코드
#include <iostream>
using namespace std;
void init(int cube[6][3][3]){
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]=i;
}
}
}
}
char face[7]="UDFBLR";
char color[7]="wyrogb";
int matrix[6][4]={ {2,5,3,4},{2,4,3,5},{0,4,1,5},{0,5,1,4},{0,3,1,2},{0,2,1,3} };//ccw - represent reference side and next side w/ ccw
int refer[6][4]={ {0,0,0,0},{2,2,2,2},{2,1,0,3},{0,1,2,3},{3,1,3,3},{1,1,1,3} };//ccw - represent turn part
int turn[4][3]={ {0,1,2},{2,5,8},{8,7,6},{6,3,0} };
void makeSide(int cube[6][3][3], int side[3], int f){
int r=matrix[f][0];
for(int i=0; i<3; i++){
int y=turn[refer[f][0]][i]/3, x=turn[refer[f][0]][i]%3;
side[i]=cube[r][y][x];
}
}
void printCube(int cube[6][3][3]){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
cout << color[cube[0][i][j]];
}
cout << "\n";
}
}
void turnSide(int cube[6][3][3], int side[3], int f, bool ccw){
for(int i=3; i; i--){
int tar, r;
int t = (ccw?i:(4-i));
int tt=(ccw?((i+1)%4):3-i);
r = matrix[f][t];
tar = matrix[f][tt];
for(int j=0; j<3; j++){
int y=turn[refer[f][t]][j]/3, x=turn[refer[f][t]][j]%3;
int ty=turn[refer[f][tt]][j]/3, tx=turn[refer[f][tt]][j]%3;
cube[tar][ty][tx]=cube[r][y][x];
}
}
int last = (ccw?1:3);
for(int i=0; i<3; i++){
int y=turn[refer[f][last]][i]/3, x=turn[refer[f][last]][i]%3;
cube[matrix[f][last]][y][x] = side[i];
}
}
void turnFace(int cube[6][3][3], int next[3][3], int f){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
cube[f][i][j]=next[i][j];
}
}
}
void rotateCube(int cube[6][3][3], int f, bool ccw){
int next[3][3];
if(!ccw){
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
next[j][2-i]=cube[f][i][j];
}
}
}
else{
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
next[2-j][i]=cube[f][i][j];
}
}
}
turnFace(cube, next, f);
int side[3];
makeSide(cube, side, f);
turnSide(cube, side, f, ccw);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int TC;
cin >> TC;
while(TC--){
int N;
cin >> N;
int cube[6][3][3];
init(cube);
while(N--){
char f, t;
cin >> f >> t;
for(int i=0; i<6; i++){
if(face[i]==f){
if(t=='+') rotateCube(cube,i,0);
else rotateCube(cube,i,1);
break;
}
}
}
printCube(cube);
}
return 0;
}
개선할 점
- 큐브를 펼쳐서 전개도로 생각하게 될 경우 훨씬 쉽다.
- 그니까 구현할 때 조금 더 효율적인 방법을 생각해보자.
여담이지만 이 문제를 이렇게 구현하면서 조금 고통받았지만 덕분에 구현력이 조금 올라간 느낌적인 느낌이다.
때로는 힘든 길이 도움이 되기도…
Leave a comment