백준 5373 - 큐빙

Updated:

Java

5373 번 - 큐빙

문제

루빅스 큐브는 삼차원 퍼즐이다. 보통 루빅스 큐브는 3×3×3개의 작은 정육면체로 이루어져 있다. 퍼즐을 풀려면 각 면에 있는 아홉 개의 작은 정육면체의 색이 동일해야 한다.
큐브는 각 면을 양방향으로 90도 만큼 돌릴 수 있도록 만들어져 있다. 회전이 마친 이후에는, 다른 면을 돌릴 수 있다. 이렇게 큐브의 서로 다른 면을 돌리다 보면, 색을 섞을 수 있다.
이 문제에서는 루빅스 큐브가 모두 풀린 상태에서 시작한다. 윗 면은 흰색, 아랫 면은 노란색, 앞 면은 빨간색, 뒷 면은 오렌지색, 왼쪽 면은 초록색, 오른쪽 면은 파란색이다.
루빅스 큐브를 돌린 방법이 순서대로 주어진다. 이때, 모두 돌린 다음에 가장 윗 면의 색상을 구하는 프로그램을 작성하시오.

문제 출처

접근 방법

다른 개발자 분들이 푸신 것에 비해 단순하게, 오직 하드코딩으로만 해결하였다.
3차원 배열을 생성하여, 1차 인덱스를 [0: 윗 면, 1: 앞 면, 2: 오른쪽 면, 3: 뒷 면, 4: 왼쪽 면, 5: 아랫 면]으로 설정하였으며, 각 면을 바라보는 방향으로 2차원으로 나타내었다.

각 면이 돌아갈때 2차원 배열을 90도 회전시키고, 각 배열을 하나씩 대입해가며 색을 이동시켰다.
색을 이동시킬 때, 동시에 색을 입혀 겹치는 경우를 방지하기 위해 순서를 중요하게 보았으며,
순서를 변경해도 겹치는 부분은 백업한 내용을 대입하여 해결하였다.

구현

하드 코딩으로 해결하였기 때문에, 해결하는 과정에서 잔 실수가 많아 찾는데 고생하였다.
따라서 온라인으로 큐브를 돌려보고, 다양한 테스트 케이스를 직접 대입해 보며 해결하였다.
큐브

테스트 케이스

INPUT

15
1
L-
2
F+ B+
4
U- D- L+ R+
10
L- U- L+ U- L- U- U- L+ U+ U+
8
B+ R+ B- R- B- U- B+ U+
11
L- U- L+ F+ U+ F- L- U+ L+ U+ U+
10
L- U- L+ F+ U+ U+ F- L- U+ L+
12
L+ R- F+ L- R+ U+ U+ L+ R- F+ L- R+
24
L+ U+ D- B+ B+ U+ D- U+ D- F+ U- U- F- U+ D- U+ D- B+ B+ U- D+ L- U+ U+
2
U+ U-
4
D+ D+ D+ D+
4
F- F- F- F-
2
B- B+
4
L+ L+ L- L-
4
R- R- R+ R+

OUTPUT

rww
rww
rww

bbb
www
ggg

gwg
owr
bwb

gwo
www
rww

ogw
www
www

wwo
wwo
rrw

obo
wwo
www

wgw
wwo
www

www
gwb
www

www
www
www

www
www
www

www
www
www

www
www
www

www
www
www

www
www
www

코드

/*
5373번 - 큐빙
https://www.acmicpc.net/problem/5373
*/

import java.util.*;
import java.io.*;

public class Main {
	
	static char cube[][][];
	static char color[] = {'w','r','b','o','g','y'};
	
    public static void main(String []args) throws IOException {        
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    	StringTokenizer st; 
    	
    	cube = new char[6][3][3]; 
    	
    	int n = stoi(br.readLine());
    	while(n-- != 0) {
    		init();
    		int nn = stoi(br.readLine());
    		st = new StringTokenizer(br.readLine());
    		while(nn-- != 0) {
    			String mv = st.nextToken();
    			char[] temp = new char[3];
    			char[] temp2 = new char[3];
    			switch(mv){
    			case "U+":
    				goPlus(0);
    				temp = cube[1][0].clone();
    				for(int i = 1; i <= 3; i++) {
    					cube[i][0] = cube[i + 1][0].clone();
    				}
    				cube[4][0] = temp.clone();
    				break;
    			case "U-":
    				goMinus(0);
    				temp = cube[4][0].clone();
    				for(int i = 4; i > 1 ; i--) {
    					cube[i][0] = cube[i - 1][0].clone();
    				}
    				cube[1][0] = temp.clone();
    				break;
    			case "F+":
    				goPlus(1);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[4][2-i][2];
    					temp2[i] = cube[2][2-i][0];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[2][i][0] = cube[0][2][i];
    					cube[0][2][i] = temp[i];
    					cube[4][i][2] = cube[5][0][i];
    					cube[5][0][i] = temp2[i];
    				}
    				break;
    			case "F-":
    				goMinus(1);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[0][2][2-i];
    					temp2[i] = cube[5][0][2-i];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[5][0][i] = cube[4][i][2];
    					cube[4][i][2] = temp[i];
    					cube[0][2][i] = cube[2][i][0];
    					cube[2][i][0] = temp2[i];
    				}
    				break;
    			case "R+":
    				goPlus(2);
    				
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[3][2-i][0];
    					temp2[i] = cube[0][2-i][2];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[0][i][2] = cube[1][i][2];
    					cube[1][i][2] = cube[5][i][2];
    					cube[5][i][2] = temp[i];
    					cube[3][i][0] = temp2[i];
    				}
    				break;
    			case "R-":
    				goMinus(2);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[3][2-i][0];
    					temp2[i] = cube[5][2-i][2];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[5][i][2] = cube[1][i][2];
    					cube[1][i][2] = cube[0][i][2];
    					cube[0][i][2] = temp[i];
    					cube[3][i][0] = temp2[i];
    				}
    				break;
    			case "B+":
    				goPlus(3);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[0][0][2-i];
    					temp2[i] = cube[5][2][2-i];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[5][2][i] = cube[4][i][0];
    					cube[4][i][0] = temp[i];
    					cube[0][0][i] = cube[2][i][2];
    					cube[2][i][2] = temp2[i];
    				}
    				break;
    			case "B-":
    				goMinus(3);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[4][2-i][0];
    					temp2[i] = cube[2][2-i][2];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[2][i][2] = cube[0][0][i];
    					cube[0][0][i] = temp[i];
    					cube[4][i][0] = cube[5][2][i];
    					cube[5][2][i] = temp2[i];
    				}
    				break;
    			case "L+":
    				goPlus(4);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[5][2 - i][0];
    					temp2[i] = cube[3][2 - i][2];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[5][i][0] 	= cube[1][i][0];
    					cube[1][i][0] 	= cube[0][i][0];
    					cube[0][i][0] 	= temp2[i];
    					cube[3][i][2] 	= temp[i];
    				}
    				break;
    			case "L-":
    				goMinus(4);
    				for(int i = 0; i < 3; i++) {
    					temp[i]  = cube[0][2 - i][0];
    					temp2[i] = cube[3][2 - i][2];
    				}
    				for(int i = 0; i < 3; i++) {
    					cube[0][i][0] = cube[1][i][0];
    					cube[1][i][0] = cube[5][i][0];
    					cube[5][i][0] = temp2[i];
    					cube[3][i][2] = temp[i];
    				}
    				break;
    			case "D+":
    				goPlus(5);
    				temp = cube[4][2].clone();
    				for(int i = 4; i > 1 ; i--) {
    					cube[i][2] = cube[i - 1][2].clone();
    				}
    				cube[1][2] = temp.clone();
    				break;
    			case "D-":
    				goMinus(5);
    				temp = cube[1][2].clone();
    				for(int i = 1; i <= 3; i++) {
    					cube[i][2] = cube[i + 1][2].clone();
    				}
    				cube[4][2] = temp.clone();
    				break;
    			}
    			
    		}
    		for(int i = 0; i < 3; i++) {
    			for(int j = 0; j< 3; j++) {
    				System.out.print(cube[0][i][j]);
    			}
    			System.out.println();
    		}
    	}  	
    	br.close();
    }
    // 큐브 초기화
    static void init() {
    	for(int i = 0; i < 6; i++) {
    		for(int j = 0; j < 3; j++) {
    			for(int k = 0; k < 3; k++) {
    				cube[i][j][k] = color[i];
    			}
    		}
    	}
    }
    // 대상 면을 시계 방향으로 돌린다.
    static void goPlus(int idx) {
    	char tmp[][] = new char[3][3];
    	
    	for(int i = 0; i < 3; i++) {
    		for(int j = 0; j < 3; j++) {
    			tmp[i][j] = cube[idx][i][j];
    		}
    	}
    	for(int i = 0; i < 3; i++) {
    		for(int j = 0; j < 3; j++) {
    			cube[idx][j][2 - i] = tmp[i][j];
    		}
    	}
    }
    // 대상 면을 반시계 방향으로 돌린다.
    static void goMinus(int idx) {
    	char tmp[][] = new char[3][3];
    	
    	for(int i = 0; i < 3; i++) {
    		for(int j = 0; j < 3; j++) {
    			tmp[i][j] = cube[idx][i][j];
    		}
    	}
    	for(int i = 0; i < 3; i++) {
    		for(int j = 0; j < 3; j++) {
    			cube[idx][2 - j][i] = tmp[i][j];
    		}
    	}
    }
    
    static int stoi(String str) {
    	return Integer.parseInt(str);
    }
}

총평

난이도

⭐⭐⭐⭐⭐

후기

너무 아찔한 문제.
온갖 공간 지각 능력을 동원하여 해결하였다.
삼성 기출 문제이던데, 이 것을 시간내에 풀어야 한다는 것에 충격이었다.

개선할 점

포기하지 않고 해결한 스스로에게 따봉을 드립니다.