Study hard
(c++)백준 5373번: 큐빙 본문
5373번: 큐빙
각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란
www.acmicpc.net
[풀이]
풀이를 생각하는 것 자체는 어렵지 않지만 하드코딩이다보니 실수하기도 쉽고 오류 찾기가 쉽지 않았다..
반례를 봐도 찾기 어려워서 백준 질문하기에 누군가 올려둔 큐브 사이트에 들어가서 하나하나 돌려보며 내 코드의 결과와 비교해보고 겨우 찾아냈다.
구현 방법
- 큐브전체를 한 배열 담지 않고 윗면, 아랫면, 앞면, 뒷면, 오른면, 왼면 각각 3*3배열을 만들었다.
- 각각 면을 돌렸을 때 다른 면들의 상태가 어떻게 변할지 그려가면서 구현하였다.
#include <iostream>
#include <vector>
using namespace std;
struct Turn {
char area;//돌릴 면
char dir;//방향
};
int T, n;
Turn Way[1001];//돌리는 방법 순서대로 저장. 인덱스 0~n-1
char Up[3][3];
char Down[3][3];
char Front[3][3];
char Back[3][3];
char Left[3][3];
char Right[3][3];
//각 면 색 초기화
void init() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
Up[i][j] = 'w';
Down[i][j] = 'y';
Front[i][j] = 'r';
Back[i][j] = 'o';
Left[i][j] = 'g';
Right[i][j] = 'b';
}
}
}
//면만 돌리는 함수(모든 면 동일 작동)
void TurnArea(char Area[][3], char dir) {
//시계방향
if (dir == '+') {
int t = 2;
while (t--) {
int tmp = Area[0][0];
//왼쪽변
for (int i = 0; i < 2; i++) {
Area[i][0] = Area[i + 1][0];
}
//아래쪽 변
for (int i = 0; i < 2; i++) {
Area[2][i] = Area[2][i + 1];
}
//오른쪽 변
for (int i = 2; i > 0; i--) {
Area[i][2] = Area[i - 1][2];
}
//위쪽 변
Area[0][2] = Area[0][1];
Area[0][1] = tmp;
}
}
//반시계 방향
else if (dir == '-') {
int t = 2;
while (t--) {
int tmp = Area[2][0];
//왼쪽 변
for (int i = 2; i > 0; i--) {
Area[i][0] = Area[i - 1][0];
}
//위쪽 변
for (int i = 0; i < 2; i++) {
Area[0][i] = Area[0][i + 1];
}
//오른쪽 변
for (int i = 0; i < 2; i++) {
Area[i][2] = Area[i + 1][2];
}
//아래쪽 변
Area[2][2] = Area[2][1];
Area[2][1] = tmp;
}
}
}
void TurnUp(char dir) {
//윗면 돌리기
TurnArea(Up, dir);
//시계 방향
if (dir == '+') {
//다른 면들 상태 바꾸기
//왼쪽면 0행 빼두기
char temp[3] = { Left[0][0],Left[0][1],Left[0][2] };
//앞면 0행 왼쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Left[0][i] = Front[0][i];
}
//오른쪽면 0행 앞면 0행으로
for (int i = 0; i <= 2; i++) {
Front[0][i] = Right[0][i];
}
//뒤쪽면 0행 오른쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Right[0][i] = Back[0][i];
}
//빼둔 왼쪽면 0행 뒤쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Back[0][i] = temp[i];
}
}
//반시계 방향
else if (dir == '-') {
//다른 면들 상태 바꾸기
//왼쪽면 0행 빼두기
char temp[3] = { Left[0][0],Left[0][1],Left[0][2] };
//뒤쪽면 0행 왼쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Left[0][i] = Back[0][i];
}
//오른쪽면 0행 뒤쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Back[0][i] = Right[0][i];
}
//앞쪽면 0행 오른쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Right[0][i] = Front[0][i];
}
//빼둔 왼쪽면 0행 앞쪽면 0행으로
for (int i = 0; i <= 2; i++) {
Front[0][i] = temp[i];
}
}
}
void TurnDown(char dir) {
//아랫면 돌리기
TurnArea(Down, dir);
//시계 방향
if (dir == '+') {
//다른 면들 상태 바꾸기
//왼쪽면 2행 빼두기
char temp[3] = { Left[2][0],Left[2][1],Left[2][2] };
//뒤쪽면 2행 왼쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Left[2][i] = Back[2][i];
}
//오른쪽면 2행 뒤쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Back[2][i] = Right[2][i];
}
//앞쪽면 2행 오른쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Right[2][i] = Front[2][i];
}
//빼둔 왼쪽면 2행 앞쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Front[2][i] = temp[i];
}
}
//반시계 방향
else if (dir == '-') {
//다른 면들 상태 바꾸기
//왼쪽면 2행 빼두기
char temp[3] = { Left[2][0],Left[2][1],Left[2][2] };
//앞면 2행 왼쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Left[2][i] = Front[2][i];
}
//오른쪽면 2행 앞면 2행으로
for (int i = 0; i <= 2; i++) {
Front[2][i] = Right[2][i];
}
//뒤쪽면 2행 오른쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Right[2][i] = Back[2][i];
}
//빼둔 왼쪽면 2행 뒤쪽면 2행으로
for (int i = 0; i <= 2; i++) {
Back[2][i] = temp[i];
}
}
}
void TurnFront(char dir) {
//앞면 돌리기
TurnArea(Front, dir);
//시계방향
if (dir == '+') {
//다른 면들 상태 바꾸기
//왼면 2열 빼두기
char temp[3] = { Left[0][2],Left[1][2],Left[2][2] };
//아랫면 0행 왼면 2열로
for (int i = 0; i < 3; i++) {
Left[i][2] = Down[0][i];
}
//오른면 0열 아랫면 0행으로
for (int i = 0; i < 3; i++) {
Down[0][2-i] = Right[i][0];
}
//윗면 2행 오른면 0열로
for (int i = 0; i < 3; i++) {
Right[i][0] = Up[2][i];
}
//빼둔 왼면 2열 윗면 2행으로
for (int i = 0; i < 3; i++) {
Up[2][2-i] = temp[i];
}
}
//반시계 방향
else if (dir == '-') {
//다른 면들 상태 바꾸기
//왼면 2열 빼두기
char temp[3] = { Left[0][2],Left[1][2],Left[2][2] };
//윗면 2행 왼면 2열로
for (int i = 0; i < 3; i++) {
Left[2 - i][2] = Up[2][i];
}
//오른면 0열 윗면 2행으로
for (int i = 0; i < 3; i++) {
Up[2][i] = Right[i][0];
}
//아랫면 0행 오른면 0열로
for (int i = 0; i < 3; i++) {
Right[2 - i][0] = Down[0][i];
}
//빼둔 왼면 2열 아랫면 0행으로
for (int i = 0; i < 3; i++) {
Down[0][i] = temp[i];
}
}
}
void TurnBack(char dir) {
//뒷면 돌리기
TurnArea(Back, dir);
//시계방향
if (dir == '+') {
//다른 면 상태 바꿔주기
//오른면 2열 빼두기
char temp[3] = { Right[0][2],Right[1][2],Right[2][2] };
//아래면 2행 오른면 2열로
for (int i = 0; i < 3; i++) {
Right[2-i][2] = Down[2][i];
}
//왼면 0열 아랫면 2행으로
for (int i = 0; i < 3; i++) {
Down[2][i] = Left[i][0];
}
//윗면 0행 왼면 0열로
for (int i = 0; i < 3; i++) {
Left[2 - i][0] = Up[0][i];
}
//빼둔 오른면 2열 윗면 0행으로
for (int i = 0; i < 3; i++) {
Up[0][i] = temp[i];
}
}
//반시계방향
else if (dir == '-') {
//다른 면 상태 바꿔주기
//오른면 2열 빼두기
char temp[3] = { Right[0][2],Right[1][2],Right[2][2] };
//윗면 0행 오른면 2열로
for (int i = 0; i < 3; i++) {
Right[i][2] = Up[0][i];
}
//왼면 0열 윗면 0행으로
for (int i = 0; i < 3; i++) {
Up[0][2 - i] = Left[i][0];
}
//아랫면 2행 왼면 0열로
for (int i = 0; i < 3; i++) {
Left[i][0] = Down[2][i];
}
//빼둔 오른면 2열 아랫면 2행으로
for (int i = 0; i < 3; i++) {
Down[2][2 - i] = temp[i];
}
}
}
void TurnLeft(char dir) {
//왼면 돌리기
TurnArea(Left, dir);
//시계 방향
if (dir == '+') {
//다른 면들 상태 바꿔주기
//뒷면 2열 빼두기
char temp[3] = { Back[0][2],Back[1][2],Back[2][2] };
//아랫면 0열 뒷면 2열로
for (int i = 0; i < 3; i++) {
Back[2-i][2] = Down[i][0];
}
//앞면 0열 아래면 0열로
for (int i = 0; i < 3; i++) {
Down[i][0] = Front[i][0];
}
//윗면 0열 앞면 0열로
for (int i = 0; i < 3; i++) {
Front[i][0] = Up[i][0];
}
//빼둔 뒷면 2열 윗면 0열로
for (int i = 0; i < 3; i++) {
Up[2 - i][0] = temp[i];
}
}
//반시계 방향
else if (dir == '-') {
//다른 면들 상태 바꿔주기
//뒷면 2열 빼두기
char temp[3] = { Back[0][2],Back[1][2],Back[2][2] };
//윗면 0열 뒷면 2열로
for (int i = 0; i < 3; i++) {
Back[2 - i][2] = Up[i][0];
}
//앞면 0열 윗면 0열로
for (int i = 0; i < 3; i++) {
Up[i][0] = Front[i][0];
}
//아랫면 0열 앞면 0열로
for (int i = 0; i < 3; i++) {
Front[i][0] = Down[i][0];
}
//빼둔 뒷면 2열 아랫면 0열로
for (int i = 0; i < 3; i++) {
Down[2 - i][0] = temp[i];
}
}
}
void TurnRight(char dir) {
//오른면 돌리기
TurnArea(Right, dir);
//시계 방향
if (dir == '+') {
//다른 면들 상태 바꿔주기
//앞면 2열 빼두기
char temp[3] = { Front[0][2],Front[1][2],Front[2][2] };
//아랫면 2열 앞면 2열로
for (int i = 0; i < 3; i++) {
Front[i][2] = Down[i][2];
}
//뒷면 0열 아랫면 2열로
for (int i = 0; i < 3; i++) {
Down[2 - i][2] = Back[i][0];
}
//윗면 2열 뒷면 0열로
for (int i = 0; i < 3; i++) {
Back[2 - i][0] = Up[i][2];
}
//빼둔 앞면 2열 윗면 2열로
for (int i = 0; i < 3; i++) {
Up[i][2] = temp[i];
}
}
//반시계 방향
else if (dir == '-') {
//다른 면들 상태 바꿔주기
//앞면 2열 빼두기
char temp[3] = { Front[0][2],Front[1][2],Front[2][2] };
//윗면 2열 앞면 2열로
for (int i = 0; i < 3; i++) {
Front[i][2] = Up[i][2];
}
//뒷면 0열 윗면 2열로
for (int i = 0; i < 3; i++) {
Up[2 - i][2] = Back[i][0];
}
//아랫면 2열 뒷면 0열로
for (int i = 0; i < 3; i++) {
Back[2 - i][0] = Down[i][2];
}
//빼둔 앞면 2열 아랫면 2열로
for (int i = 0; i < 3; i++) {
Down[i][2] = temp[i];
}
}
}
void TurnCube() {
for (int i = 0; i < n; i++) {
char area = Way[i].area;
char dir = Way[i].dir;
//윗면을 돌릴 경우
if (area == 'U') {
TurnUp(dir);
}
//아랫면 돌릴 경우
else if (area == 'D') {
TurnDown(dir);
}
//앞면 돌릴 경우
else if (area == 'F') {
TurnFront(dir);
}
//뒷면
else if (area == 'B') {
TurnBack(dir);
}
//왼면
else if (area == 'L') {
TurnLeft(dir);
}
//오른면
else if (area == 'R') {
TurnRight(dir);
}
}
}
void solution() {
cin >> T;
while (T--) {
//색 초기화
init();
cin >> n;
for (int i = 0; i < n; i++) {
cin >> Way[i].area >> Way[i].dir;
}
TurnCube();
//cout << "Up" << '\n';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << Up[i][j];
}
cout << '\n';
}
/*
cout << "Down" << '\n';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << Down[i][j];
}
cout << '\n';
}
cout << "Front" << '\n';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << Front[i][j];
}
cout << '\n';
}
cout << "Back" << '\n';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << Back[i][j];
}
cout << '\n';
}
cout << "Left" << '\n';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << Left[i][j];
}
cout << '\n';
}
cout << "Right" << '\n';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << Right[i][j];
}
cout << '\n';
}
*/
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
solution();
return 0;
}
'백준 > 시뮬레이션,구현' 카테고리의 다른 글
(c++)백준 17143번: 낚시왕 (0) | 2020.10.17 |
---|---|
(c++)백준 16235번: 나무 재테크 (0) | 2020.10.16 |
(c++)백준 3190번: 뱀 (0) | 2020.10.15 |
(c++)백준 19235번: 모노미노도미노 (0) | 2020.10.14 |
(c++)백준 19237번: 어른 상어 (0) | 2020.10.14 |