感觉这道题真的是很好的一道题,我比较认可这个方法就是按照读入顺序来对颜色块,进行编码然后预先打表处理出每个面顺逆时针旋转之后的位置,认真一点把表打对,然后可以利用迭代加深搜索出最小的步数。
#include <bits/stdc++.h>
using namespace std;
char readchar() {
char ch = 0;
while (!isalpha(ch)) {
ch = getchar();
}
return ch;
}
char cube[54];
const int cell[6][9] = { //每行第一个都是块的中心 以读入的顺序来对每个颜色进行编号
{4, 0, 1, 2, 3, 5, 6, 7, 8},
{22, 9, 10, 11, 21, 23, 33, 34, 35},
{25, 12, 13, 14, 24, 26, 36, 37, 38},
{28, 15, 16, 17, 27, 29, 39, 40, 41},
{31, 18, 19, 20, 30, 32, 42, 43, 44},
{49, 45, 46, 47, 48, 50, 51, 52, 53}
};
const int change[12][20] = { //一共12行分别表示0~5面的顺逆时针旋转,每次只旋转20个,因为中心快永远都不会动
{11, 23, 35, 34, 33, 21, 9, 10, 51, 48, 45, 36, 24, 12, 6, 3, 0, 20, 32, 44},
{9, 10, 11, 23, 35, 34, 33, 21, 36, 24, 12, 6, 3, 0, 20, 32, 44, 51, 48, 45},
{14, 13, 26, 38, 37, 36, 24, 12, 45, 46, 47, 39, 27, 15, 8, 7, 6, 11, 23, 35},
{12, 24, 13, 14, 26, 38, 37, 36, 39, 27, 15, 8, 7, 6, 11, 23, 35, 45, 46, 47},
{17, 29, 41, 40, 39, 27, 15, 16, 47, 50, 53, 42, 30, 18, 2, 5, 8, 14, 26, 38},
{15, 16, 17, 29, 41, 40, 39, 27, 42, 30, 18, 2, 5, 8, 14, 26, 38, 47, 50, 53},
{18, 19, 20, 32, 44, 43, 42, 30, 53, 52, 51, 33, 21, 9, 0, 1, 2, 17, 29, 41},
{42, 30, 18, 19, 20, 32, 44, 43, 33, 21, 9, 0, 1, 2, 17, 29, 41, 53, 52, 51},
{0, 1, 2, 5, 8, 7, 6, 3, 12, 13, 14, 15, 16, 17, 18, 19, 20, 9, 10, 11},
{6, 3, 0, 1, 2, 5, 8, 7, 15, 16, 17, 18, 19, 20, 9, 10, 11, 12, 13, 14},
{45, 46, 47, 50, 53, 52, 51, 48, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33},
{51, 48, 45, 46, 47, 50, 53, 52, 41, 40, 39, 38, 37, 36, 35, 34, 33, 44, 43, 42}
};
bool ok() {
for (int i = 0; i < 6; ++i) {
for (int j = 1; j < 9; ++j) {
if (cube[cell[i][0]] != cube[cell[i][j]])
return false;
}
}
return true;
}
void rotate(int layer) {
char prv[54];
copy(cube, cube + 54, prv);
for (int i = 0; i < 20; ++i) {
prv[change[layer][i]] = cube[change[layer ^ 1][i]];
}//利用异或颠倒奇偶性的性质
copy(prv, prv + 54, cube);
}
int ans[10];
bool dfs(int d, int limit) { //dfs
if (d > limit) return false;
if (ok()) return true;
for (int i = 0; i < 12; ++i) {
ans[d] = i;
rotate(i); //转一下
if (dfs(d + 1, limit)) return true;
rotate(i ^ 1); //再转回来
}
return false;
}
int main() {
int t; scanf("%d", &t);
while (t--) {
for (int i = 0; i < 54; ++i) cube[i] = readchar();
for (int i = 0; ; ++i) { // 迭代加深
if (6 == i) {
printf("-1\n");
break;
}
if (dfs(0, i)) {
if (0 == i)
printf("0\n");
else {
printf("%d\n", i);
for (int j = 0; j < i; ++j) {
printf("%d %d\n", ans[j] / 2, ((ans[j] & 1) ? -1 : 1));
}
}
break;
}
}
}
return 0;
}