-
BOJ 5373: 큐빙알고리즘 2023. 8. 15. 13:26
#BOJ 5373: 큐빙
5373번: 큐빙
각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란
www.acmicpc.net
#풀이
큐브를 돌려서 윗면에 어떤 색깔이 있는지 출력하는 문제이다.
큐브는 각 면을 바라보는 상태에서 +는 시계방향 -는 반시게방향으로 돌릴 수 있다.
큐브를 돌리면 바라보는 면이 아닌 주위에 있는 9개의 칸이 변경된다.
나는 처음에 큐브는 사각형이므로 무조건 반대편과 함께 움직이는 것을 생각하여 해결하려고 했지만 너무 머리가 아파 그냥 1차원적으로 생각하여 풀었다.
큐브를 돌릴 때 변화되는 큐브의 각 칸들을 대입시켜줬다.
앞 면 : 빨간색 아랫 면: 노란색 윗 면 : 하얀색 왼쪽 면 : 초록색 오른쪽 면 : 파란색 뒷 면 : 오렌지색 위에 사진 처럼 3X3 큐브에 인덱스를 정해줬다.
큐브를 돌리때 바라보고 있는 면이 90도로 변한다.
+ 입력 시 바라보고 있는 면의 색깔을 시계방향으로 바꿔줘야 한다.
위에 사진처럼 1번 인덱스자리에 7번 인덱스가 가지고 있는 값을 대입하면 된다.
- 입력 시 바라보고 있는 면의 색깔을 시계방향으로 바꿔줘야 한다.
위에 사진처럼 1번 인덱스자리에 7번 인덱스가 가지고 있는 값을 대입하면 된다.
사실 90도 회전은 많이 했을 거라 생각한다. 하지만 대부분 2차원 좌표라서 식을 사용하면 편하지만
문제가 구현인지라 너무 복잡하면 실수가 너무 많이 나오기 때문에 그냥 1차원으로 생각하여 풀게 되었다.
간단하게 U+를 생각해보자
윗 면을 바라보고 시계방향으로 돌린 다음 빨간색을 보면 인덱스(1,2,3) 이 왼쪽으로 90도 돌린 것으로 생각할 수 있을 것이다.
(1,2,3) 의 값이 (37,38,39)의 값으로 변해 있을 것이다.
(37,38,39) ->(46,47,48)
(46,47,48) ->(28,29,30)
(28,29,30) ->(1,2,3)
또한 윗 면에 있는 값들을 시게방향으로 변경해줘야 한다.
모든 큐브의 움직임에 대해서 이런 식으로 구현을 해주면 된다.
나는 모든 큐브의 움직임이 동일하다고 생각하여
tmp[4] 배열을 만들어 사용 했다.
U를 예를 들자.
if (clock == '+') { char tmp[4] = { arr[1], arr[37], arr[46], arr[28] }; // 배열을 선언할 때 순서를 잘 생각해서 해줘야 한다. arr[1] = tmp[1]; arr[37] = tmp[2]; arr[46] = tmp[3]; arr[28] = tmp[0]; tmp[0] = arr[2]; tmp[1] = arr[38]; tmp[2] = arr[47]; tmp[3] = arr[29]; arr[2] = tmp[1]; arr[38] = tmp[2]; arr[47] = tmp[3]; arr[29] = tmp[0]; tmp[0] = arr[3]; tmp[1] = arr[39]; tmp[2] = arr[48]; tmp[3] = arr[30]; arr[3] = tmp[1]; arr[39] = tmp[2]; arr[48] = tmp[3]; arr[30] = tmp[0]; //윗면 회전 +이므로 시계방향 char tmp2[9] = { arr[19], arr[20], arr[21], arr[22], arr[23], arr[24], arr[25], arr[26], arr[27] }; arr[19] = tmp2[6]; arr[20] = tmp2[3]; arr[21] = tmp2[0]; arr[22] = tmp2[7]; //arr[23]은 그대로 arr[24] = tmp2[1]; arr[25] = tmp2[8]; arr[26] = tmp2[5]; arr[27] = tmp2[2];// } else { char tmp[4] = { arr[1], arr[37], arr[46], arr[28] }; arr[1] = tmp[3]; arr[37] = tmp[0]; arr[46] = tmp[1]; arr[28] = tmp[2]; tmp[0] = arr[2]; tmp[1] = arr[38]; tmp[2] = arr[47]; tmp[3] = arr[29]; arr[2] = tmp[3]; arr[38] = tmp[0]; arr[47] = tmp[1]; arr[29] = tmp[2]; tmp[0] = arr[3]; tmp[1] = arr[39]; tmp[2] = arr[48]; tmp[3] = arr[30]; arr[3] = tmp[3]; arr[39] = tmp[0]; arr[48] = tmp[1]; arr[30] = tmp[2]; //윗면 회전 -이므로 반시계방향 회전 char tmp2[9] = { arr[19], arr[20], arr[21], arr[22], arr[23], arr[24], arr[25], arr[26], arr[27] }; arr[19] = tmp2[2]; arr[20] = tmp2[5]; arr[21] = tmp2[8]; arr[22] = tmp2[1]; //arr[23]은 그대로 arr[24] = tmp2[7]; arr[25] = tmp2[0]; arr[26] = tmp2[3]; arr[27] = tmp2[6]; }
위의 코드를 보면 arr에 tmp원소를 대입할 때
+일 때 tmp인덱스
(1,2,3,0)
-일 때 tmp인덱스
(3,0,1,2)
모든 큐브를 돌릴 때 tmp 인덱스를 동일하게 사용하였다.
이렇게 사용하기 위해선 tmp배열 원소의 순서를 지켜줘야 한다.
나는 한점을 기준으로 +방향으로 돌렸을 시 기준인 칸에 오는 인덱스의 방향으로 배열을 초기화 하였다.
조금의 팁이 있다면
L 이나 R 을 입력받을 때 뒷 면에 대해서 생각해 줘야 한다. 뒷면은 앞면과 반대로 되어 있다.
뒷 면이 움직일 때
L : 1과 52가 매칭
R : 3과 54 매칭
뭔가 손에 큐브가 있다면 정말 좋겠지만 우리는 테스트를 볼 때 큐브를 손에 들고 갈 수 없으므로....
머리속으로 상상해서 풀어야 한다...
#코드
#include<iostream> using namespace std; int t; void funcU(char * arr,char clock) { // 윗 면 +:왼쪽 -: 오른쪽 if (clock == '+') { char tmp[4] = { arr[1], arr[37], arr[46], arr[28] }; arr[1] = tmp[1]; arr[37] = tmp[2]; arr[46] = tmp[3]; arr[28] = tmp[0]; tmp[0] = arr[2]; tmp[1] = arr[38]; tmp[2] = arr[47]; tmp[3] = arr[29]; arr[2] = tmp[1]; arr[38] = tmp[2]; arr[47] = tmp[3]; arr[29] = tmp[0]; tmp[0] = arr[3]; tmp[1] = arr[39]; tmp[2] = arr[48]; tmp[3] = arr[30]; arr[3] = tmp[1]; arr[39] = tmp[2]; arr[48] = tmp[3]; arr[30] = tmp[0]; char tmp2[9] = { arr[19], arr[20], arr[21], arr[22], arr[23], arr[24], arr[25], arr[26], arr[27] }; arr[19] = tmp2[6]; arr[20] = tmp2[3]; arr[21] = tmp2[0]; arr[22] = tmp2[7]; //arr[23]은 그대로 arr[24] = tmp2[1]; arr[25] = tmp2[8]; arr[26] = tmp2[5]; arr[27] = tmp2[2];// } else { char tmp[4] = { arr[1], arr[37], arr[46], arr[28] }; arr[1] = tmp[3]; arr[37] = tmp[0]; arr[46] = tmp[1]; arr[28] = tmp[2]; tmp[0] = arr[2]; tmp[1] = arr[38]; tmp[2] = arr[47]; tmp[3] = arr[29]; arr[2] = tmp[3]; arr[38] = tmp[0]; arr[47] = tmp[1]; arr[29] = tmp[2]; tmp[0] = arr[3]; tmp[1] = arr[39]; tmp[2] = arr[48]; tmp[3] = arr[30]; arr[3] = tmp[3]; arr[39] = tmp[0]; arr[48] = tmp[1]; arr[30] = tmp[2]; char tmp2[9] = { arr[19], arr[20], arr[21], arr[22], arr[23], arr[24], arr[25], arr[26], arr[27] }; arr[19] = tmp2[2]; arr[20] = tmp2[5]; arr[21] = tmp2[8]; arr[22] = tmp2[1]; //arr[23]은 그대로 arr[24] = tmp2[7]; arr[25] = tmp2[0]; arr[26] = tmp2[3]; arr[27] = tmp2[6]; } } void funcD(char* arr,char clock) { // 아랫 면 +:오른쪽 -:왼쪽 // 2222 if (clock == '+') {//1 char tmp[4] = { arr[7], arr[34], arr[52], arr[43] }; arr[7] = tmp[1]; arr[34] = tmp[2]; arr[52] = tmp[3]; arr[43] = tmp[0]; tmp[0] = arr[8]; tmp[1] = arr[35]; tmp[2] = arr[53]; tmp[3] = arr[44]; arr[8] = tmp[1]; arr[35] = tmp[2]; arr[53] = tmp[3]; arr[44] = tmp[0]; tmp[0] = arr[9]; tmp[1] = arr[36]; tmp[2] = arr[54]; tmp[3] = arr[45]; arr[9] = tmp[1]; arr[36] = tmp[2]; arr[54] = tmp[3]; arr[45] = tmp[0]; char tmp2[9] = { arr[10], arr[11], arr[12], arr[13], arr[14], arr[15], arr[16], arr[17], arr[18] }; arr[10] = tmp2[6]; arr[11] = tmp2[3]; arr[12] = tmp2[0]; arr[13] = tmp2[7]; //arr[24]은 그대로 arr[15] = tmp2[1]; arr[16] = tmp2[8]; arr[17] = tmp2[5]; arr[18] = tmp2[2];// } else {//1 char tmp[4] = { arr[7], arr[34], arr[52], arr[43] }; arr[7] = tmp[3]; arr[34] = tmp[0]; arr[52] = tmp[1]; arr[43] = tmp[2]; tmp[0] = arr[8]; tmp[1] = arr[35]; tmp[2] = arr[53]; tmp[3] = arr[44]; arr[8] = tmp[3]; arr[35] = tmp[0]; arr[53] = tmp[1]; arr[44] = tmp[2]; tmp[0] = arr[9]; tmp[1] = arr[36]; tmp[2] = arr[54]; tmp[3] = arr[45]; arr[9] = tmp[3]; arr[36] = tmp[0]; arr[54] = tmp[1]; arr[45] = tmp[2]; char tmp2[9] = { arr[10], arr[11], arr[12], arr[13], arr[14], arr[15], arr[16], arr[17], arr[18] }; arr[10] = tmp2[2]; arr[11] = tmp2[5]; arr[12] = tmp2[8]; arr[13] = tmp2[1]; //arr[14]은 그대로 arr[15] = tmp2[7]; arr[16] = tmp2[0]; arr[17] = tmp2[3]; arr[18] = tmp2[6]; } } void funcF(char* arr,char clock) { // 앞 면+: 시계 -:반시계 if (clock == '+') { // 1 char tmp[4] = { arr[25], arr[36], arr[12], arr[37] }; arr[25] = tmp[1]; arr[36] = tmp[2]; arr[12] = tmp[3]; arr[37] = tmp[0]; tmp[0] = arr[26]; tmp[1] = arr[33]; tmp[2] = arr[11]; tmp[3] = arr[40]; arr[26] = tmp[1]; arr[33] = tmp[2]; arr[11] = tmp[3]; arr[40] = tmp[0]; tmp[0] = arr[27]; tmp[1] = arr[30]; tmp[2] = arr[10]; tmp[3] = arr[43]; arr[27] = tmp[1]; arr[30] = tmp[2]; arr[10] = tmp[3]; arr[43] = tmp[0]; char tmp2[9] = { arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8], arr[9] }; arr[1] = tmp2[6]; arr[2] = tmp2[3]; arr[3] = tmp2[0]; arr[4] = tmp2[7]; //arr[15]은 그대로 arr[6] = tmp2[1]; arr[7] = tmp2[8]; arr[8] = tmp2[5]; arr[9] = tmp2[2]; } else { // 1 char tmp[4] = { arr[25], arr[36], arr[12], arr[37] }; arr[25] = tmp[3]; arr[36] = tmp[0]; arr[12] = tmp[1]; arr[37] = tmp[2]; tmp[0] = arr[26]; tmp[1] = arr[33]; tmp[2] = arr[11]; tmp[3] = arr[40]; arr[26] = tmp[3]; arr[33] = tmp[0]; arr[11] = tmp[1]; arr[40] = tmp[2]; tmp[0] = arr[27]; tmp[1] = arr[30]; tmp[2] = arr[10]; tmp[3] = arr[43]; arr[27] = tmp[3]; arr[30] = tmp[0]; arr[10] = tmp[1]; arr[43] = tmp[2]; char tmp2[9] = { arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8], arr[9] }; arr[1] = tmp2[2]; arr[2] = tmp2[5]; arr[3] = tmp2[8]; arr[4] = tmp2[1]; //arr[15]은 그대로 arr[6] = tmp2[7]; arr[7] = tmp2[0]; arr[8] = tmp2[3]; arr[9] = tmp2[6]; } } void funcB(char* arr,char clock) { // 뒷 면 오른쪽면 기준+: 왼쪽 - :오른쪽 // 2 if (clock == '+') { // 1 char tmp[4] = { arr[19], arr[39], arr[18], arr[34] }; arr[19] = tmp[1]; arr[39] = tmp[2]; arr[18] = tmp[3]; arr[34] = tmp[0]; tmp[0] = arr[20]; tmp[1] = arr[42]; tmp[2] = arr[17]; tmp[3] = arr[31]; arr[20] = tmp[1]; arr[42] = tmp[2]; arr[17] = tmp[3]; arr[31] = tmp[0]; tmp[0] = arr[21]; tmp[1] = arr[45]; tmp[2] = arr[16]; tmp[3] = arr[28]; arr[21] = tmp[1]; arr[45] = tmp[2]; arr[16] = tmp[3]; arr[28] = tmp[0]; char tmp2[9] = { arr[46], arr[47], arr[48], arr[49], arr[50], arr[51], arr[52], arr[53], arr[54] }; arr[46] = tmp2[6]; arr[47] = tmp2[3]; arr[48] = tmp2[0]; arr[49] = tmp2[7]; //arr[50]은 그대로 arr[51] = tmp2[1]; arr[52] = tmp2[8]; arr[53] = tmp2[5]; arr[54] = tmp2[2]; } else { // 1 char tmp[4] = { arr[19], arr[39], arr[18], arr[34] }; arr[19] = tmp[3]; arr[39] = tmp[0]; arr[18] = tmp[1]; arr[34] = tmp[2]; tmp[0] = arr[20]; tmp[1] = arr[42]; tmp[2] = arr[17]; tmp[3] = arr[31]; arr[20] = tmp[3]; arr[42] = tmp[0]; arr[17] = tmp[1]; arr[31] = tmp[2]; tmp[0] = arr[21]; tmp[1] = arr[45]; tmp[2] = arr[16]; tmp[3] = arr[28]; arr[21] = tmp[3]; arr[45] = tmp[0]; arr[16] = tmp[1]; arr[28] = tmp[2]; char tmp2[9] = { arr[46], arr[47], arr[48], arr[49], arr[50], arr[51], arr[52], arr[53], arr[54] }; arr[46] = tmp2[2]; arr[47] = tmp2[5]; arr[48] = tmp2[8]; arr[49] = tmp2[1]; //arr[50]은 그대로 arr[51] = tmp2[7]; arr[52] = tmp2[0]; arr[53] = tmp2[3]; arr[54] = tmp2[6]; } } void funcL(char* arr,char clock) { // 왼쪽 면 +: 아래 -: 위로 if (clock == '+') { // 1 char tmp[4] = { arr[1], arr[19], arr[54], arr[10] }; arr[1] = tmp[1]; arr[19] = tmp[2]; arr[54] = tmp[3]; arr[10] = tmp[0]; tmp[0] = arr[4]; tmp[1] = arr[22]; tmp[2] = arr[51]; tmp[3] = arr[13]; arr[4] = tmp[1]; arr[22] = tmp[2]; arr[51] = tmp[3]; arr[13] = tmp[0]; tmp[0] = arr[7]; tmp[1] = arr[25]; tmp[2] = arr[48]; tmp[3] = arr[16]; arr[7] = tmp[1]; arr[25] = tmp[2]; arr[48] = tmp[3]; arr[16] = tmp[0]; char tmp2[9] = { arr[28], arr[29], arr[30], arr[31], arr[32], arr[33], arr[34], arr[35], arr[36] }; arr[28] = tmp2[6]; arr[29] = tmp2[3]; arr[30] = tmp2[0]; arr[31] = tmp2[7]; //arr[32]은 그대로 arr[33] = tmp2[1]; arr[34] = tmp2[8]; arr[35] = tmp2[5]; arr[36] = tmp2[2]; } else { // 1 char tmp[4] = { arr[1], arr[19], arr[54], arr[10] }; arr[1] = tmp[3]; arr[19] = tmp[0]; arr[54] = tmp[1]; arr[10] = tmp[2]; tmp[0] = arr[4]; tmp[1] = arr[22]; tmp[2] = arr[51]; tmp[3] = arr[13]; arr[4] = tmp[3]; arr[22] = tmp[0]; arr[51] = tmp[1]; arr[13] = tmp[2]; tmp[0] = arr[7]; tmp[1] = arr[25]; tmp[2] = arr[48]; tmp[3] = arr[16]; arr[7] = tmp[3]; arr[25] = tmp[0]; arr[48] = tmp[1]; arr[16] = tmp[2]; char tmp2[9] = { arr[28], arr[29], arr[30], arr[31], arr[32], arr[33], arr[34], arr[35], arr[36] }; arr[28] = tmp2[2]; arr[29] = tmp2[5]; arr[30] = tmp2[8]; arr[31] = tmp2[1]; //arr[32]은 그대로 arr[33] = tmp2[7]; arr[34] = tmp2[0]; arr[35] = tmp2[3]; arr[36] = tmp2[6]; } } void funcR(char* arr,char clock) { // 오른쪽 면 +:위 -:아래 if (clock == '+') { // 1 char tmp[4] = { arr[3], arr[12], arr[52], arr[21] }; arr[3] = tmp[1]; arr[12] = tmp[2]; arr[52] = tmp[3]; arr[21] = tmp[0]; tmp[0] = arr[6]; tmp[1] = arr[15]; tmp[2] = arr[49]; tmp[3] = arr[24]; arr[6] = tmp[1]; arr[15] = tmp[2]; arr[49] = tmp[3]; arr[24] = tmp[0]; tmp[0] = arr[9]; tmp[1] = arr[18]; tmp[2] = arr[46]; tmp[3] = arr[27]; arr[9] = tmp[1]; arr[18] = tmp[2]; arr[46] = tmp[3]; arr[27] = tmp[0]; char tmp2[9] = { arr[37], arr[38], arr[39], arr[40], arr[41], arr[42], arr[43], arr[44], arr[45] }; arr[37] = tmp2[6]; arr[38] = tmp2[3]; arr[39] = tmp2[0]; arr[40] = tmp2[7]; //arr[41]은 그대로 arr[42] = tmp2[1]; arr[43] = tmp2[8]; arr[44] = tmp2[5]; arr[45] = tmp2[2]; } else { // 1 char tmp[4] = { arr[3], arr[12], arr[52], arr[21] }; arr[3] = tmp[3]; arr[12] = tmp[0]; arr[52] = tmp[1]; arr[21] = tmp[2]; tmp[0] = arr[6]; tmp[1] = arr[15]; tmp[2] = arr[49]; tmp[3] = arr[24]; arr[6] = tmp[3]; arr[15] = tmp[0]; arr[49] = tmp[1]; arr[24] = tmp[2]; tmp[0] = arr[9]; tmp[1] = arr[18]; tmp[2] = arr[46]; tmp[3] = arr[27]; arr[9] = tmp[3]; arr[18] = tmp[0]; arr[46] = tmp[1]; arr[27] = tmp[2]; char tmp2[9] = { arr[37], arr[38], arr[39], arr[40], arr[41], arr[42], arr[43], arr[44], arr[45] }; arr[37] = tmp2[2]; arr[38] = tmp2[5]; arr[39] = tmp2[8]; arr[40] = tmp2[1]; //arr[41]은 그대로 arr[42] = tmp2[7]; arr[43] = tmp2[0]; arr[44] = tmp2[3]; arr[45] = tmp2[6]; } } int main() { ios::sync_with_stdio(0); cin.tie(0); cin >> t; while (t--) { char arr[55] = { 0,'r','r','r','r' ,'r' ,'r' ,'r' ,'r' ,'r' ,'y','y','y','y','y','y','y','y','y' ,'w','w','w','w','w','w','w','w','w' ,'g','g','g','g','g','g','g','g','g' ,'b','b','b','b','b','b','b','b','b' ,'o','o','o','o','o','o','o','o','o' }; int n; cin >> n; for (int i = 1; i <= n; i++) { char dir, clock; cin >> dir >> clock; if (dir == 'U') { // 윗 면 funcU(arr,clock); } else if (dir == 'D') { // 아랫 면 funcD(arr, clock); } else if (dir == 'F') { // 앞 면 funcF(arr, clock); } else if (dir == 'B') { // 뒷 면 funcB(arr,clock); } else if (dir == 'L') { // 왼쪽 면 funcL(arr, clock); } else if (dir == 'R') { // 오른쪽 면 funcR(arr, clock); } } for (int i = 19; i <= 27; i++) { cout << arr[i]; if (i % 3 == 0) cout << '\n'; } } return 0; }
'알고리즘' 카테고리의 다른 글
BOJ 16236: 아기 상어 (0) 2023.08.16 BOJ 16235: 나무 재테크 (0) 2023.08.15 BOJ 16234: 인구 이동 (0) 2023.08.13 BOJ 15685: 드래곤 커브 (0) 2023.08.13 BOJ 14890: 경사로 (0) 2023.08.13