Study hard

(c++)백준 5373번: 큐빙 본문

백준/시뮬레이션,구현

(c++)백준 5373번: 큐빙

Nimgnoej 2020. 10. 15. 19:57

www.acmicpc.net/problem/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;
}