0. 개요

https://www.acmicpc.net/problem/5373
Simulation 통한 큐브 회전을 구현

1. 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include <cstdio>
#include <algorithm>
#include <vector>
#include <deque>
#include <cstring>

using namespace std;

/*
면의 번호
0 : U, 1 : F
2 : L, 3 : R
4 : B, 5 : D
*/
char cube[6][3][3];
char sChar[8] = "wrgboy";

// cube 데이터를 통해 4면을 이어붙인 2차원 배열
char board[3][12];

void init()
{
	for (int d = 0; d < 6; d++)
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++)
				cube[d][i][j] = sChar[d];
}

// 90도 회전
void rotate90(char arr[3][3], bool isPositive)
{
	char temp[3][3];
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (isPositive)
				temp[j][2 - i] = arr[i][j];
			else
				temp[i][j] = arr[j][2 - i];
		}
	}
	memcpy(arr, temp, sizeof(temp));
}

// cube 데이터를 통해 4면 이어진 board 중 idx의 위치에 세팅하는 함수
// idx : 4면 중 어느 위치에 붙일지에 대한 index
// dir : 이어 붙일 면 번호
void importBoard(int idx, int dir, int rotateCnt)
{
	char tmp[3][3];
	memcpy(tmp, cube[dir], sizeof(tmp));

	for (int i = 0; i < rotateCnt; i++)
		rotate90(tmp, true);

	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			board[i][idx * 3 + j] = tmp[i][j];
}

// 4면을 이어붙인 board로부터 해당 idx의 cube 데이터 가져오기
// idx : 4면 중 어느 위치에 붙일지에 대한 index
// dir : 가져올 면 번호
void exportBoard(int idx, int dir, int rotateCnt)
{
	char tmp[3][3];
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			tmp[i][j] = board[i][j + idx * 3];

	for (int i = 0; i < rotateCnt; i++)
		rotate90(tmp, true);

	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++)
			cube[dir][i][j] = tmp[i][j];
}

// 연산을 수행하는 함수
int func(char direction, bool isPositive)
{
	memset(board, 0, sizeof(board));

	deque<char> deq;
	int dir[4]; 	// direction이 맨 윗면이라고 가정했을 때의 이어붙인 4면의 번호
	int rotate[4]; 	// direction 각각의 회전 각도 (각도 = value * 90도)
	int idx; 		// direction의 면 번호

	switch (direction)
	{
	case 'U':
	{
		dir[0] = 2, dir[1] = 1, dir[2] = 3, dir[3] = 4;
		rotate[0] = 0, rotate[1] = 0, rotate[2] = 0, rotate[3] = 0;
		idx = 0;
		break;
	}
	case 'D':
	{
		dir[0] = 3, dir[1] = 1, dir[2] = 2, dir[3] = 4;
		rotate[0] = 2, rotate[1] = 2, rotate[2] = 2, rotate[3] = 2;
		idx = 5;
		break;
	}
	case 'F':
	{
		dir[0] = 2, dir[1] = 5, dir[2] = 3, dir[3] = 0;
		rotate[0] = 3, rotate[1] = 2, rotate[2] = 1, rotate[3] = 2;
		idx = 1;
		break;
	}
	case 'B':
	{
		dir[0] = 3, dir[1] = 5, dir[2] = 2, dir[3] = 0;
		rotate[0] = 3, rotate[1] = 0, rotate[2] = 1, rotate[3] = 0;
		idx = 4;
		break;
	}
	case 'R':
	{
		dir[0] = 1, dir[1] = 5, dir[2] = 4, dir[3] = 0;
		rotate[0] = 3, rotate[1] = 1, rotate[2] = 1, rotate[3] = 3;
		idx = 3;
		break;
	}
	case 'L':
	{
		dir[0] = 4, dir[1] = 5, dir[2] = 1, dir[3] = 0;
		rotate[0] = 3, rotate[1] = 3, rotate[2] = 1, rotate[3] = 1;
		idx = 2;
		break;
	}
	default:
		break;
	}

	for (int i = 0; i < 4; i++)
		importBoard(i, dir[i], rotate[i]);

	for (int j = 0; j < 12; j++)
		deq.push_back(board[0][j]);
	if (isPositive)
	{
		for (int i = 0; i < 3; i++)
		{
			char item = deq.front();
			deq.pop_front();
			deq.push_back(item);
		}
	}
	else
	{
		for (int i = 0; i < 3; i++)
		{
			char item = deq.back();
			deq.pop_back();
			deq.push_front(item);
		}
	}
	for (int j = 0; j < 12; j++)
		board[0][j] = deq[j];

	rotate90(cube[idx], isPositive);

	for (int i = 0; i < 4; i++)
		exportBoard(i, dir[i], (4 - rotate[i]) % 4);

	return 0;
}

int main()
{
	freopen("in.txt", "r", stdin);

	int testcase = 0;
	scanf("%d", &testcase);

	for (int tc = 1; tc <= testcase; tc++)
	{
		init();

		int N = 0;
		scanf("%d", &N);

		for (int i = 0; i < N; i++)
		{
			char input[3];
			scanf("%s", input);
			func(input[0], input[1] == '+' ? true : false);
		}

		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 3; j++)
				printf("%c", cube[0][i][j]);
			printf("\n");
		}
	}
}

2. 풀이

cube-planar Figure

  1. 회전하게 되는 면을 0도의 올바른 상태로 윗면에 위치시킨다.
  2. 그때 side에 있는 4면을 각도를 고려하여 이어 붙여 하나의 2차원 배열에 저장한다.
  3. 2차원 배열의 제일 위에 있는 row의 데이터를 회전 방향에 따라 deq로 pop & push 한다.