백준 알고리즘 5373_큐빙 C

2021. 2. 25. 12:00CODING

문제

(링크)5373번: 큐빙 (acmicpc.net)

 

5373번: 큐빙

각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란

www.acmicpc.net

사고과정

이전에 풀었던 주사위 문제와 비슷한 결이다. 주의해야할 점은 각 면을 바라볼 때 어디를 기준으로 삼을 것인가 이다. 또한 큐브를 돌릴 때 변하는 것들의 index에 유의해야한다. 

먼저 회전하는 면의 중심점을 기준으로 주위 8칸을 회전시켜준다. 이후 회전면과 맞닿아 있는 면들을 3칸씩 shift한다. 

 

내코드

#include <stdio.h>
#include <stdlib.h>
#define white 0
#define red 1
#define yellow 2
#define orange 3
#define green 4
#define blue 5

int initial_cube[6][3][3];

void clear_cube(int cube[][3][3]) {
	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] = initial_cube[i][j][k];
			}
		}
	}
}

int dx[8] = { -1,0,1,1,1,0,-1,-1 };
int dy[8] = { -1,-1,-1,0,1,1,1,0 };

void spin_cube(int O, char dir,int cube[][3][3]) {
	if (dir == '+') {		//clockwise
		int tmp[2] = { cube[O][1][0],cube[O][2][0] };
		for (int i = 7; i >= 2; i--) {
			cube[O][1 + dy[i]][1 + dx[i]] = cube[O][1 + dy[i - 2]][1 + dx[i - 2]];
		}
		cube[O][0][1] = tmp[0];
		cube[O][0][0] = tmp[1];
		
	}
	else if (dir == '-') {	//oppoclockwise
		int tmp[2] = { cube[O][0][0],cube[O][0][1] };
		for (int i = 0; i <= 5; i++) {
			cube[O][1 + dy[i]][1 + dx[i]] = cube[O][1 + dy[i + 2]][1 + dx[i + 2]];
		}
		cube[O][2][0] = tmp[0];
		cube[O][1][0] = tmp[1];
	}
}


void play_cube(char plane, char dir, int cube[][3][3]) {
	if (plane == 'U') {
		spin_cube(0, dir, cube);
		int tmp[3];
		if (dir == '+') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[3][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][0][i] = cube[4][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][0][i] = cube[1][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][0][i] = cube[5][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][0][i] = tmp[i];
			}
		}
		else if (dir == '-') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[3][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][0][i] = cube[5][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][0][i] = cube[1][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][0][i] = cube[4][0][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][0][i] = tmp[i];
			}
		}
	}
	else if (plane == 'F') {
		spin_cube(1, dir, cube);
		int tmp[3];
		if (dir == '+') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][2][i] = cube[4][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][2 - i][2] = cube[2][0][2 - i];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][0][2 - i] = cube[5][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][i][0] = tmp[i];
			}
		}
		else if (dir == '-') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][2][i] = cube[5][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][i][0] = cube[2][0][2 - i];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][0][2 - i] = cube[4][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][2 - i][2] = tmp[i];
			}
		}
	}
	else if (plane == 'D') {
		spin_cube(2, dir, cube);
		int tmp[3];
		if (dir == '-') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[1][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][2][i] = cube[5][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][2][i] = cube[3][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][2][i] = cube[4][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][2][i] = tmp[i];
			}
		}
		else if (dir == '+') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[1][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][2][i] = cube[4][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][2][i] = cube[3][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][2][i] = cube[5][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][2][i] = tmp[i];
			}
		}
	}
	else if (plane == 'B') {
		spin_cube(3, dir, cube);
		int tmp[3];
		if (dir == '+') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][0][2 - i];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][0][2 - i] = cube[5][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][2 - i][2] = cube[2][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][2][i] = cube[4][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][i][0] = tmp[i];
			}
		}
		else if (dir == '-') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][0][2 - i];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][0][2 - i] = cube[4][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[4][i][0] = cube[2][2][i];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][2][i] = cube[5][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[5][2 - i][2] = tmp[i];
			}
		}
	}
	else if (plane == 'L') {
		spin_cube(4, dir, cube);
		int tmp[3];
		if (dir == '+') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][i][0] = cube[3][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][2 - i][2] = cube[2][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][i][0] = cube[1][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][i][0] = tmp[i];
			}
		}
		else if (dir == '-') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][i][0] = cube[1][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][i][0] = cube[2][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][i][0] = cube[3][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][2 - i][2] = tmp[i];
			}
		}
	}
	else if (plane == 'R') {
		spin_cube(5, dir, cube);
		int tmp[3];
		if (dir == '+') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][2 - i][2] = cube[1][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][2 - i][2] = cube[2][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][2 - i][2] = cube[3][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][i][0] = tmp[i];
			}
		}
		else if (dir == '-') {
			for (int i = 0; i < 3; i++) {
				tmp[i] = cube[0][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[0][2 - i][2] = cube[3][i][0];
			}
			for (int i = 0; i < 3; i++) {
				cube[3][i][0] = cube[2][2 - i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[2][2 - i][2] = cube[1][2-i][2];
			}
			for (int i = 0; i < 3; i++) {
				cube[1][2-i][2] = tmp[i];
			}
		}
	}
}

void print_cube(int cube[][3][3]) {
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			if (cube[0][i][j] == white) {
				printf("w");
			}
			else if (cube[0][i][j] == red) {
				printf("r");
			}
			else if (cube[0][i][j] == yellow) {
				printf("y");
			}
			else if (cube[0][i][j] == orange) {
				printf("o");
			}
			else if (cube[0][i][j] == green) {
				printf("g");
			}
			else if (cube[0][i][j] == blue) {
				printf("b");
			}
		}
		printf("\n");
	}
}

int main() {
	for (int i = 0; i < 6; i++) {
		for (int j = 0; j < 3; j++) {
			for (int k = 0; k < 3; k++) {
				initial_cube[i][j][k] = i;
			}
		}
	}

	int test_case;
	scanf("%d", &test_case);

	for (int i = 0; i < test_case; i++) {
		int spin_num;
		scanf("%d", &spin_num);
		char* command = (char*)malloc((2 * spin_num + 1) * sizeof(char));
		for (int j = 0; j < spin_num; j++) {
			scanf(" %c%c", &command[2*j], &command[2 * j+1]);
		}

		int temp_cube[6][3][3];	
		//초기화
		clear_cube(temp_cube);
		for (int j = 0; j < spin_num; j++) {			
			//회전 및 출력
			play_cube(command[2*j], command[2*j + 1], temp_cube);			
		}
		print_cube(temp_cube);

		free(command);
	}
	return 0;
}

큐브를 돌리는 코드라 각 경우에 따라 index를 다르게 설정해줘야 해서 길이가 길어졌지만, 결국 입력의 경우에 따라 철저하게 분류해내는 것이 다인 문제이다. 사실 큐브를 문자열로 만들었으면 코드가 짧아졌을 것이지만 시작을 정수형으로 하여 다시 바꾸기 너무 귀찮았다. 어쨌든 큐브를 회전할 때, 회전 방향에 따라 각 인접한 면의 index만 잘 조절해주면 큰 문제없이 코드를 완성할 수 있다.

  

피드백

나중에 문자열로도 코드를 만들어 볼것.