문제 출처
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번을 실행시키면, 해당 방향과 반대 방향 구현이 가능하다.