#include<stdio.h>
#include<string.h>
using namespace std;
int T,deep;
char s[60] ;
int cent[7] = {5,23,26,29,32,50} ;//每个面的中心点
int ex[7][9] = {{1,2,3,4,6,7,8,9},
{10,11,12,22,24,34,35,36},
{13,14,15,25,27,37,38,39},
{16,17,18,28,30,40,41,42},
{19,20,21,31,33,43,44,45},
{46,47,48,49,51,52,53,54}
} ;
int get_h(){//以每个面与中心不同的数的和作为估值函数
int res = 0 ;
for(int i=0;i<6;i++){
int c = 0 ;
for(int j=0;j<8;j++){
if(s[ex[i][j]]!=s[cent[i]]) c++ ;
}
res += c ;
}
return res ;
}
int wh[10], dd[10] ;
/*
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
*/
int ope[12][20] = { //用预处理的数组来代替每一种旋转,节约时间。
{1,4,7,13,25,37,46,49,52,21,33,45,10,11,12,24,36,35,34,22},
{45,33,21,1,4,7,13,25,37,52,49,46,34,22,10,11,12,24,36,35},
{7,8,9,16,28,40,48,47,46,36,24,12,13,14,15,27,39,38,37,25},
{36,24,12,7,8,9,16,28,40,48,47,46,37,25,13,14,15,27,39,38},
{9,6,3,19,31,43,54,51,48,39,27,15,16,17,18,30,42,41,40,28},
{39,27,15,9,6,3,19,31,43,54,51,48,40,28,16,17,18,30,42,41},
{42,30,18,3,2,1,10,22,34,52,53,54,19,20,21,33,45,44,43,31},
{52,53,54,42,30,18,3,2,1,10,22,34,43,31,19,20,21,33,45,44},
{15,14,13,12,11,10,21,20,19,18,17,16,1,2,3,6,9,8,7,4},
{18,17,16,15,14,13,12,11,10,21,20,19,7,4,1,2,3,6,9,8},
{37,38,39,40,41,42,43,44,45,34,35,36,46,47,48,51,54,53,52,49},
{34,35,36,37,38,39,40,41,42,43,44,45,52,49,46,47,48,51,54,53}
} ;
bool dfs(int d){
char maze[60] ;
int h = get_h();
if(d+(h+11)/12 > deep) return false ;//一次旋转最多使12个块归位
if(h==0 && d==deep) return true ;
for(int i=0;i<12;i++){
memcpy(maze,s,sizeof(s));
for(int j=0;j<20;j++){
s[ope[i][j]] = maze[ope[i^1][j]];
}
wh[d] = i/2 ;
if((i&1)==0) dd[d] = 1;
else dd[d] = -1 ;
if(dfs(d+1)) return true ;
memcpy(s,maze,sizeof(maze));
}
}
int main(){
//freopen("1in","r",stdin) ;
//freopen("1out","w",stdout);
scanf("%d",&T);
while(T--){
for(int i=1;i<=54;i++){
scan(s[i]);
}
if(get_h() == 0){
printf("0\n") ; continue ;
}
deep = 1 ;
while(deep <= 5){
if(dfs(0)) break ;
deep ++ ;
}
if(deep > 5){
printf("-1\n");
}
else{
printf("%d\n",deep);
for(int i=0;i<deep;i++){
printf("%d %d\n",wh[i],dd[i]) ;
}
}
}
return 0;
}
3阶魔方的处理
最新推荐文章于 2022-12-09 01:11:10 发布