ZOJ Magic Cube 2477

来源:互联网 发布:茂名荔枝网络品牌 编辑:程序博客网 时间:2024/06/06 05:19

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2477

最大深度只有5层, 用IDA* 算法, 这题的亮点就是用数组来预处理模方的每种旋转,节约时间和代码量 。

h函数的选择: 因为无论怎么旋转,每块魔方的中间位置的颜色是不会变的,因此可以用总共不在原来面上的方块数来作为h函数。 每次旋转,最多能使12块魔方回到原来的面上。

代码:

/*ZOJ 2477 Magic CubeTips : IDA*runtime 0msMemory : 180K*/#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  910 11 12 13 14 15 16 17 18 19 20 2122 23 24 25 26 27 28 29 30 31 32 3334 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 ;    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));    }}void scan(char &c){    char cc ;    while(cc=getchar() , cc<'a'||cc>'z') ;    c = cc ;}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;}