https://www.acmicpc.net/problem/5373
이 문제는 그냥 구현을 하는 문제라 문제를 읽고 이해하는데에는 크게 어렵지 않았으나... 세부 구현을 하는 것이 너무 복잡? 헷갈렸다.
주어진 조건을 보면 100개의 테스트케이스와 1000개의 이동을 하므로 한 이동을 1000번 안에만 수행하면 아주 넉넉하게 풀 수 있다. 사실 이동에 1000번 걸릴 일이 없기 때문에 진짜 구현만 하면 된다. 다만 이 구현에서 너무 오랜 시간이 걸렸다.
처음에는 그냥 vector을 만들고 하나 돌릴때 돌리는 면은 시계 방향으로 (혹은 반대) 돌리고 그와 접하는 면들을 같이 다른 면으로 이동시켜 주면 되는 생각보다는 간단한 문제이다.
다만 이 접하는 면을 돌리는게 엄청 골때리는데 면을 어딜 기준으로 삼든 면끼리 돌릴때 행과 열이 같지 않아서 이걸 위치는 하나하나 저장을 해줘야 한다... 처음에 이걸 종이에 안쓰고 풀겠다고 해서 엄청 헷갈려서 나중에는 종이에다 면 하나하나 그려가면서 했는데 그걸 해도 많이 헷갈렸고 이상한 실수도 많이 해서 시간을 오래 잡아먹었다.
이걸 대회에서 보면 어떻게 풀어야 하나 싶다.
다른 사람들은 이걸 전개도로 그리고 자리 하나하나를 54개를 다 지정해서 돌릴때마다 바뀌는 걸 하나하나 했던데 내 것이나 다른 사람 것이나 둘다 노가다인 것은 똑같고 내거 같은 경우에는 상대적인 위치 정하는게 너무 너무 너무 빡세서 그냥 그렇게 하는것도 나쁘진 않아 보인다.
근데 머릿속에 큐브 돌리면서 그 결과를 전개도로 작성하는 것도 쉽진 않을 것 같아서...
다음에 보면 이 방법과 똑같은 방법을 사용하지 않을까 싶다. 아마 그때는 1시간 30분 정도는 걸리지 않을까 생각한다. 잘하면 1시간? 그리고 깝치지 말고 바로 종이를 사용해야 된다 생각한다.
(집에 큐브없어서 고생했다.)
걸린 시간 : 3시간 5분 19초
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <utility>
using namespace std;
#define UP 0 // 바라봤을때 BACK이 위
#define DOWN 1 // 바라봤을때 BACK이 위
#define FRONT 2 // 바라봤을때 UP이 위
#define BACK 3 // 바라봤을때 UP이 위
#define RIGHT 4 // 바라봤을때 UP이 위
#define LEFT 5 // 바라봤을때 UP이 위
#define WHITE 0
#define YELLOW 1
#define RED 2
#define ORANGE 3
#define GREEN 4
#define BLUE 5
#define CLOCKWIDE 0
#define COUNTER_CLOCKWIDE 1
vector<char> color(6, 0);
// 면을 시계 방향 or 반대 방향으로 바꾸기
void rotationClockwide(vector<vector<vector<int>>>& cube, int rotation, int side) {
if (rotation == CLOCKWIDE) {
vector<vector<int>> temp(3, vector<int>(3, 0));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
temp[i][j] = cube[side][2 - j][i]; // 대충 식세워 만들고 검증해봄
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cube[side][i][j] = temp[i][j];
}
}
}
else{
vector<vector<int>> temp(3, vector<int>(3, 0));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
temp[i][j] = cube[side][j][2 - i];
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cube[side][i][j] = temp[i][j];
}
}
}
}
void rotationCounterClockwide(vector<vector<vector<int>>> cube, int side) {
}
// 면과 접하는 부분을 돌리기
void rotationUp(vector<vector<vector<int>>>& cube, int rotation) {
vector<int> clockwide(5, 0); // 시계방향으로 했을때 다음 어디 면으로 이동해야 하는가
clockwide[0] = FRONT;
clockwide[1] = LEFT;
clockwide[2] = BACK;
clockwide[3] = RIGHT;
clockwide[4] = FRONT;
vector<vector<pair<int, int>>> location(5, vector<pair<int, int>>(3, make_pair(0, 0))); // 면끼리 서로 다른 행, 열의 위치를 같게 맞추는 역할
location[0][0].first = 0;
location[0][0].second = 0;
location[0][1].first = 0;
location[0][1].second = 1;
location[0][2].first = 0;
location[0][2].second = 2;
location[1][0].first = 0;
location[1][0].second = 0;
location[1][1].first = 0;
location[1][1].second = 1;
location[1][2].first = 0;
location[1][2].second = 2;
location[2][0].first = 0;
location[2][0].second = 0;
location[2][1].first = 0;
location[2][1].second = 1;
location[2][2].first = 0;
location[2][2].second = 2;
location[3][0].first = 0;
location[3][0].second = 0;
location[3][1].first = 0;
location[3][1].second = 1;
location[3][2].first = 0;
location[3][2].second = 2;
location[4][0].first = 0;
location[4][0].second = 0;
location[4][1].first = 0;
location[4][1].second = 1;
location[4][2].first = 0;
location[4][2].second = 2;
if (rotation == CLOCKWIDE) {
rotationClockwide(cube, rotation, UP);
vector<int> temp(3, 0);
for (int i = 0; i < clockwide.size() - 1; i++) {
for (int j = 0; j < 3; j++) {
if (i == 0) {
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= temp2;
}
}
}
}
else {
rotationClockwide(cube, rotation, UP);
vector<int> temp(3, 0);
for (int i = clockwide.size() - 1; i > 0; i--) {
for (int j = 0; j < 3; j++) {
if (i == clockwide.size() - 1) {
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= temp2;
}
}
}
}
}
void rotationDown(vector<vector<vector<int>>>& cube, int rotation) {
vector<int> clockwide(5, 0);
clockwide[0] = FRONT;
clockwide[1] = RIGHT;
clockwide[2] = BACK;
clockwide[3] = LEFT;
clockwide[4] = FRONT;
vector<vector<pair<int, int>>> location(5, vector<pair<int, int>>(3, make_pair(0, 0))); // 면끼리 서로 다른 행, 열의 위치를 같게 맞추는 역할
location[0][0].first = 2;
location[0][0].second = 2;
location[0][1].first = 2;
location[0][1].second = 1;
location[0][2].first = 2;
location[0][2].second = 0;
location[1][0].first = 2;
location[1][0].second = 2;
location[1][1].first = 2;
location[1][1].second = 1;
location[1][2].first = 2;
location[1][2].second = 0;
location[2][0].first = 2;
location[2][0].second = 2;
location[2][1].first = 2;
location[2][1].second = 1;
location[2][2].first = 2;
location[2][2].second = 0;
location[3][0].first = 2;
location[3][0].second = 2;
location[3][1].first = 2;
location[3][1].second = 1;
location[3][2].first = 2;
location[3][2].second = 0;
location[4][0].first = 2;
location[4][0].second = 2;
location[4][1].first = 2;
location[4][1].second = 1;
location[4][2].first = 2;
location[4][2].second = 0;
if (rotation == CLOCKWIDE) {
rotationClockwide(cube, rotation, DOWN);
vector<int> temp(3, 0);
for (int i = 0; i < clockwide.size() - 1; i++) {
for (int j = 0; j < 3; j++) {
if (i == 0) {
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= temp2;
}
}
}
}
else {
rotationClockwide(cube, rotation, DOWN);
vector<int> temp(3, 0);
for (int i = clockwide.size() - 1; i > 0; i--) {
for (int j = 0; j < 3; j++) {
if (i == clockwide.size() - 1) {
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= temp2;
}
}
}
}
}
void rotationFront(vector<vector<vector<int>>>& cube, int rotation) {
vector<int> clockwide(5, 0);
clockwide[0] = UP;
clockwide[1] = RIGHT;
clockwide[2] = DOWN;
clockwide[3] = LEFT;
clockwide[4] = UP;
vector<vector<pair<int, int>>> location(5, vector<pair<int, int>>(3, make_pair(0, 0))); // 면끼리 서로 다른 행, 열의 위치를 같게 맞추는 역할
location[0][0].first = 2;
location[0][0].second = 0;
location[0][1].first = 2;
location[0][1].second = 1;
location[0][2].first = 2;
location[0][2].second = 2;
location[1][0].first = 0;
location[1][0].second = 0;
location[1][1].first = 1;
location[1][1].second = 0;
location[1][2].first = 2;
location[1][2].second = 0;
location[2][0].first = 2;
location[2][0].second = 0;
location[2][1].first = 2;
location[2][1].second = 1;
location[2][2].first = 2;
location[2][2].second = 2;
location[3][0].first = 2;
location[3][0].second = 2;
location[3][1].first = 1;
location[3][1].second = 2;
location[3][2].first = 0;
location[3][2].second = 2;
location[4][0].first = 2;
location[4][0].second = 0;
location[4][1].first = 2;
location[4][1].second = 1;
location[4][2].first = 2;
location[4][2].second = 2;
if (rotation == CLOCKWIDE) {
rotationClockwide(cube, rotation, FRONT);
vector<int> temp(3, 0);
for (int i = 0; i < clockwide.size() - 1; i++) {
for (int j = 0; j < 3; j++) {
if (i == 0) {
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= temp2;
}
}
}
}
else {
rotationClockwide(cube, rotation, FRONT);
vector<int> temp(3, 0);
for (int i = clockwide.size() - 1; i > 0; i--) {
for (int j = 0; j < 3; j++) {
if (i == clockwide.size() - 1) {
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= temp2;
}
}
}
}
}
void rotationBack(vector<vector<vector<int>>>& cube, int rotation) {
vector<int> clockwide(5, 0);
clockwide[0] = UP;
clockwide[1] = LEFT;
clockwide[2] = DOWN;
clockwide[3] = RIGHT;
clockwide[4] = UP;
vector<vector<pair<int, int>>> location(5, vector<pair<int, int>>(3, make_pair(0, 0))); // 면끼리 서로 다른 행, 열의 위치를 같게 맞추는 역할
location[0][0].first = 0;
location[0][0].second = 2;
location[0][1].first = 0;
location[0][1].second = 1;
location[0][2].first = 0;
location[0][2].second = 0;
location[1][0].first = 0;
location[1][0].second = 0;
location[1][1].first = 1;
location[1][1].second = 0;
location[1][2].first = 2;
location[1][2].second = 0;
location[2][0].first = 0;
location[2][0].second = 2;
location[2][1].first = 0;
location[2][1].second = 1;
location[2][2].first = 0;
location[2][2].second = 0;
location[3][0].first = 2;
location[3][0].second = 2;
location[3][1].first = 1;
location[3][1].second = 2;
location[3][2].first = 0;
location[3][2].second = 2;
location[4][0].first = 0;
location[4][0].second = 2;
location[4][1].first = 0;
location[4][1].second = 1;
location[4][2].first = 0;
location[4][2].second = 0;
if (rotation == CLOCKWIDE) {
rotationClockwide(cube, rotation, BACK);
vector<int> temp(3, 0);
for (int i = 0; i < clockwide.size() - 1; i++) {
for (int j = 0; j < 3; j++) {
if (i == 0) {
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= temp2;
}
}
}
}
else {
rotationClockwide(cube, rotation, BACK);
vector<int> temp(3, 0);
for (int i = clockwide.size() - 1; i > 0; i--) {
for (int j = 0; j < 3; j++) {
if (i == clockwide.size() - 1) {
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= temp2;
}
}
}
}
}
void rotationRight(vector<vector<vector<int>>>& cube, int rotation) {
vector<int> clockwide(5, 0);
clockwide[0] = UP;
clockwide[1] = BACK;
clockwide[2] = DOWN;
clockwide[3] = FRONT;
clockwide[4] = UP;
vector<vector<pair<int, int>>> location(5, vector<pair<int, int>>(3, make_pair(0, 0))); // 면끼리 서로 다른 행, 열의 위치를 같게 맞추는 역할
location[0][0].first = 2;
location[0][0].second = 2;
location[0][1].first = 1;
location[0][1].second = 2;
location[0][2].first = 0;
location[0][2].second = 2;
location[1][0].first = 0;
location[1][0].second = 0;
location[1][1].first = 1;
location[1][1].second = 0;
location[1][2].first = 2;
location[1][2].second = 0;
location[2][0].first = 0;
location[2][0].second = 0;
location[2][1].first = 1;
location[2][1].second = 0;
location[2][2].first = 2;
location[2][2].second = 0;
location[3][0].first = 2;
location[3][0].second = 2;
location[3][1].first = 1;
location[3][1].second = 2;
location[3][2].first = 0;
location[3][2].second = 2;
location[4][0].first = 2;
location[4][0].second = 2;
location[4][1].first = 1;
location[4][1].second = 2;
location[4][2].first = 0;
location[4][2].second = 2;
if (rotation == CLOCKWIDE) {
rotationClockwide(cube, rotation, RIGHT);
vector<int> temp(3, 0);
for (int i = 0; i < clockwide.size() - 1; i++) {
for (int j = 0; j < 3; j++) {
if (i == 0) {
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= temp2;
}
}
}
}
else {
rotationClockwide(cube, rotation, RIGHT);
vector<int> temp(3, 0);
for (int i = clockwide.size() - 1; i > 0; i--) {
for (int j = 0; j < 3; j++) {
if (i == clockwide.size() - 1) {
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= temp2;
}
}
}
}
}
void rotationLeft(vector<vector<vector<int>>>& cube, int rotation) {
vector<int> clockwide(5, 0);
clockwide[0] = UP;
clockwide[1] = FRONT;
clockwide[2] = DOWN;
clockwide[3] = BACK;
clockwide[4] = UP;
vector<vector<pair<int, int>>> location(5, vector<pair<int, int>>(3, make_pair(0, 0))); // 면끼리 서로 다른 행, 열의 위치를 같게 맞추는 역할
location[0][0].first = 0;
location[0][0].second = 0;
location[0][1].first = 1;
location[0][1].second = 0;
location[0][2].first = 2;
location[0][2].second = 0;
location[1][0].first = 0;
location[1][0].second = 0;
location[1][1].first = 1;
location[1][1].second = 0;
location[1][2].first = 2;
location[1][2].second = 0;
location[2][0].first = 2;
location[2][0].second = 2;
location[2][1].first = 1;
location[2][1].second = 2;
location[2][2].first = 0;
location[2][2].second = 2;
location[3][0].first = 2;
location[3][0].second = 2;
location[3][1].first = 1;
location[3][1].second = 2;
location[3][2].first = 0;
location[3][2].second = 2;
location[4][0].first = 0;
location[4][0].second = 0;
location[4][1].first = 1;
location[4][1].second = 0;
location[4][2].first = 2;
location[4][2].second = 0;
if (rotation == CLOCKWIDE) {
rotationClockwide(cube, rotation, LEFT);
vector<int> temp(3, 0);
for (int i = 0; i < clockwide.size() - 1; i++) {
for (int j = 0; j < 3; j++) {
if (i == 0) {
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second];
cube[clockwide[i + 1]][location[i + 1][j].first][location[i + 1][j].second]
= temp2;
}
}
}
}
else {
rotationClockwide(cube, rotation, LEFT);
vector<int> temp(3, 0);
for (int i = clockwide.size() - 1; i > 0; i--) {
for (int j = 0; j < 3; j++) {
if (i == clockwide.size() - 1) {
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= cube[clockwide[i]][location[i][j].first][location[i][j].second];
}
else {
int temp2 = temp[j];
temp[j] = cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second];
cube[clockwide[i - 1]][location[i - 1][j].first][location[i - 1][j].second]
= temp2;
}
}
}
}
}
int main() {
int t;
scanf("%d", &t);
color[WHITE] = 'w';
color[YELLOW] = 'y';
color[RED] = 'r';
color[ORANGE] = 'o';
color[GREEN] = 'g';
color[BLUE] = 'b';
for (int h = 0; h < t; h++) {
vector<vector<vector<int>>> cube(6, vector<vector<int>>(3, vector<int>(3, 0)));
int numOfTurn;
int rotation;
string temp;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cube[UP][i][j] = WHITE;
cube[DOWN][i][j] = YELLOW;
cube[FRONT][i][j] = RED;
cube[BACK][i][j] = ORANGE;
cube[LEFT][i][j] = GREEN;
cube[RIGHT][i][j] = BLUE;
}
}
scanf("%d", &numOfTurn);
for (int i = 0; i < numOfTurn; i++) {
cin >> temp;
if (temp[0] == 'U') {
rotationUp(cube, temp[1] == '+' ? CLOCKWIDE : COUNTER_CLOCKWIDE);
}
else if (temp[0] == 'D') {
rotationDown(cube, temp[1] == '+' ? CLOCKWIDE : COUNTER_CLOCKWIDE);
}
else if (temp[0] == 'F') {
rotationFront(cube, temp[1] == '+' ? CLOCKWIDE : COUNTER_CLOCKWIDE);
}
else if (temp[0] == 'B') {
rotationBack(cube, temp[1] == '+' ? CLOCKWIDE : COUNTER_CLOCKWIDE);
}
else if (temp[0] == 'R') {
rotationRight(cube, temp[1] == '+' ? CLOCKWIDE : COUNTER_CLOCKWIDE);
}
else if (temp[0] == 'L') {
rotationLeft(cube, temp[1] == '+' ? CLOCKWIDE : COUNTER_CLOCKWIDE);
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%c", color[cube[UP][i][j]]);
}
printf("\n");
}
}
return 0;
}