This is a very popular game for children. In this game, there‘s a cube, which consists of 3 * 3 * 3 small cubes. We can unwrap the cube, it will become like this:
w w w
w w w
w w w
r r r g g g b b b o o o
r r r g g g b b b o o o
r r r g g g b b b o o o
y y y
y y y
y y y
The letters means the color on the small cubes. For example, ‘r‘ means red, ‘g‘ means green, ‘y‘ means yellow....The goal for this game is to rotate the faces of the cube to make each of the faces contains only one color. Note there‘re exact 6 kind of colors on the cube and there‘re exact 9 small rectangles totally in any time in the game.
Do you know how to rotate the faces? I think most of you have known it. But I would like to show it again. When a face is rotated, the configuration of colors in all the adjacent faces changes. For the cube above, after we rotate the green face clock-wise, the last line of ‘w‘ face will become the left column of ‘b‘ face, the left column of ‘b‘ face will become the top line of ‘y‘ face, etc. As you may know, reaching the final position from a scrambled configuration can be quite challenging.
In this problem, you are given a configuration of the cube, and asked to give a way to reach the final position. To reduce the difficulty, the steps required will never be greater than 5.
Input
The input contains an integer in the first line, which indicates the number of the test cases. In each test case, there‘re exact 10 lines. The first line is an empty line. The next 9 lines contain a configuration. The format can be seen in the sample input. For simplicity, we give an index to each face as follows:
/---\
| |
| 4 |
| |
/---+---+---+---\
| | | | |
| 0 | 1 | 2 | 3 |
| | | | |
\---+---+---+---/
| |
| 5 |
| |
\---/
Note that there‘s a space between two adjacent letters.
Output
For each test case, the first line of the output is the smallest count N of the steps to reach the winning position. If the winning position can‘t be reached in 5 steps, print -1 in this line. Otherwise print each step in one line in the following N lines. A step contains two integers, the first one means the face index, and the second one means the direction. 1 means clock-wise and -1 means counter clock-wise. If the given position is the winning position, print 0 for such test case simply. If there‘re multiple solutions, any one is acceptable.
Sample Input
2
w w w
w w w
w w w
r r r g g g b b b o o o
r r r g g g b b b o o o
r r r g g g b b b o o o
y y y
y y y
y y y
w w w
w w w
b b b
r r w g g g y b b o o o
r r w g g g y b b o o o
r r w g g g y b b o o o
r r r
y y y
y y y
Sample Output
0
1
1 1
题意:还原一个魔方,如果超过5步,输出-1即可,否则输出最快还原步骤。
思路:题意说的不清楚,需要对着样例转一下4面和5面。一顿模拟就好了,想法很简单,但要维护旋转时位置的更替关系,写起来还是比较恶心的,,,用bfs暴力卡过,正解是IDA*,可以用所有面中不合法的颜色种类数作为估价函数。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 #define pcv pair<cube, vector<pii> > 31 32 const double pi = acos(-1.0); 33 const int INF = 0x3f3f3f3f; 34 const int MOD = 1e9 + 7; 35 const double EPS = 1e-9; 36 37 struct cube { 38 char a[6][11]; 39 cube rot(int face[], int p[][3]) { 40 cube b; 41 for (int i = 0; i < 6; ++i) { 42 for (int j = 1; j <= 9; ++j) { 43 b.a[i][j] = a[i][j]; 44 } 45 } 46 for (int i = 0; i < 4; ++i) { 47 int _i = (i + 3) % 4; 48 int f = face[i], _f = face[_i]; 49 //cout << f << ‘ ‘ << _f << endl; 50 for (int j = 0; j < 3; ++j) { 51 b.a[f][p[i][j]] = a[_f][p[_i][j]]; 52 } 53 } 54 return b; 55 } 56 cube clockwise(int face) { 57 cube b; 58 int f[4], p[4][3]; 59 if (!face) { 60 f[0] = 4, f[1] = 1, f[2] = 5, f[3] = 3; 61 p[0][0] = 1, p[0][1] = 2, p[0][2] = 3; 62 p[1][0] = 7, p[1][1] = 4, p[1][2] = 1; 63 p[2][0] = 9, p[2][1] = 8, p[2][2] = 7; 64 p[3][0] = 3, p[3][1] = 6, p[3][2] = 9; 65 } else if (1 == face) { 66 f[0] = 4, f[1] = 2, f[2] = 5, f[3] = 0; 67 p[0][0] = 1, p[0][1] = 4, p[0][2] = 7; 68 p[1][0] = 1, p[1][1] = 4, p[1][2] = 7; 69 p[2][0] = 1, p[2][1] = 4, p[2][2] = 7; 70 p[3][0] = 9, p[3][1] = 6, p[3][2] = 3; 71 } else if (2 == face) { 72 f[0] = 4, f[1] = 3, f[2] = 5, f[3] = 1; 73 p[0][0] = 7, p[0][1] = 8, p[0][2] = 9; 74 p[1][0] = 1, p[1][1] = 4, p[1][2] = 7; 75 p[2][0] = 3, p[2][1] = 2, p[2][2] = 1; 76 p[3][0] = 9, p[3][1] = 6, p[3][2] = 3; 77 } else if (3 == face) { 78 f[0] = 4, f[1] = 0, f[2] = 5, f[3] = 2; 79 p[0][0] = 9, p[0][1] = 6, p[0][2] = 3; 80 p[1][0] = 1, p[1][1] = 4, p[1][2] = 7; 81 p[2][0] = 9, p[2][1] = 6, p[2][2] = 3; 82 p[3][0] = 9, p[3][1] = 6, p[3][2] = 3; 83 } else if (4 == face) { 84 f[0] = 0, f[1] = 3, f[2] = 2, f[3] = 1; 85 for (int i = 0; i < 4; ++i) { 86 p[i][0] = 3, p[i][1] = 2, p[i][2] = 1; 87 } 88 } else { 89 f[0] = 2, f[1] = 3, f[2] = 0, f[3] = 1; 90 for (int i = 0; i < 4; ++i) { 91 p[i][0] = 7, p[i][1] = 8, p[i][2] = 9; 92 } 93 } 94 b = rot(f, p); 95 b.a[face][1] = a[face][7]; 96 b.a[face][2] = a[face][4]; 97 b.a[face][3] = a[face][1]; 98 b.a[face][4] = a[face][8]; 99 b.a[face][6] = a[face][2]; 100 b.a[face][7] = a[face][9]; 101 b.a[face][8] = a[face][6]; 102 b.a[face][9] = a[face][3]; 103 return b; 104 } 105 bool ok() { 106 for (int i = 0; i < 6; ++i) { 107 char c = a[i][1]; 108 for (int j = 2; j <= 9; ++j) { 109 if (c != a[i][j]) { 110 return false; 111 } 112 } 113 } 114 return true; 115 } 116 }; 117 int T; 118 cube a; 119 void get_a() { 120 vector<char> vec; 121 char c; 122 while (vec.size() < 54) { 123 c = getchar(); 124 if (isalpha(c)) { 125 vec.pb(c); 126 } 127 } 128 for (int i = 0; i < 9; ++i) { 129 a.a[4][i + 1] = vec[i]; 130 } 131 for (int l = 0; l < 3; ++l) { 132 for (int f = 0; f < 4; ++f) { 133 for (int i = 1; i <= 3; ++i) { 134 a.a[f][l * 3 + i] = vec[l * 12 + f * 3 + i + 8]; 135 } 136 } 137 } 138 for (int i = 1; i <= 9; ++i) { 139 a.a[5][i] = vec[44 + i]; 140 } 141 int dir[8] = {1, 2, 3, 6, 9, 8, 7, 4}; 142 int x = a.a[4][dir[7]], y = a.a[4][dir[6]]; 143 for (int i = 7; i > 2; i -= 2) { 144 a.a[4][dir[i]] = a.a[4][dir[i - 2]]; 145 a.a[4][dir[i - 1]] = a.a[4][dir[i - 3]]; 146 } 147 a.a[4][dir[1]] = x; 148 a.a[4][dir[0]] = y; 149 x = a.a[5][dir[0]]; 150 y = a.a[5][dir[1]]; 151 for (int i = 0; i < 5; i += 2) { 152 a.a[5][dir[i]] = a.a[5][dir[i + 2]]; 153 a.a[5][dir[i + 1]] = a.a[5][dir[i + 3]]; 154 } 155 a.a[5][dir[7]] = y; 156 a.a[5][dir[6]] = x; 157 /*for (int i = 0; i < 6; ++i) { 158 for (int j = 1; j <= 9; ++j) { 159 cout << a.a[i][j] << ‘ ‘; 160 } 161 cout << endl; 162 }*/ 163 } 164 queue<pcv> que; 165 int main() { 166 scanf("%d", &T); 167 while (T--) { 168 get_a(); 169 while (que.size()) { 170 que.pop(); 171 } 172 vector<pii> vec, ans; 173 que.push(mp(a, vec)); 174 int flag = 0; 175 while (que.size()) { 176 pcv pp = que.front(); que.pop(); 177 cube a = pp.first; 178 vector<pii> vec = pp.second; 179 if (a.ok()) { 180 ans = vec; 181 flag = 1; 182 break; 183 } 184 if (5 == vec.size()) continue; 185 for (int f = 0; f < 6; ++f) { 186 cube b1 = a.clockwise(f); 187 //printf("%d\n", f); pau; 188 vector<pii> vec1 = vec; 189 vec1.pb(mp(f, 1)); 190 que.push(mp(b1, vec1)); 191 cube b2 = b1.clockwise(f).clockwise(f); 192 vector<pii> vec2 = vec; 193 vec2.pb(mp(f, -1)); 194 que.push(mp(b2, vec2)); 195 } 196 } 197 if (flag) { 198 printf("%d\n", ans.size()); 199 for (int i = 0; i < ans.size(); ++i) { 200 int x = ans[i].first, y = ans[i].second; 201 printf("%d %d\n", x, y); 202 } 203 } else { 204 puts("-1"); 205 } 206 } 207 return 0; 208 } 209 /* 210 3 211 w w w 212 w w w 213 w w w 214 r r r g g g b b b o o o 215 r r r g g g b b b o o o 216 r r r g g g b b b o o o 217 y y y 218 y y y 219 y y y 220 221 w w w 222 w w w 223 b b b 224 r r w g g g y b b o o o 225 r r w g g g y b b o o o 226 r r w g g g y b b o o o 227 r r r 228 y y y 229 y y y 230 */