这个题用IDA*算法比较好,代码量也比A*小,空间消耗也小。
估价函数也比较好找,就是中间8个方格距离这8个方格同数的最短距离。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int init[30];
int sol[1010];
int bound;
bool ans;
int final;
int e[8]={6,7,8,11,12,15,16,17};
int re[8]={5,4,7,6,1,0,3,2};
int cha[4][7]={0,2,6,11,15,20,22,
1,3,8,12,17,21,23,
10,9,8,7,6,5,4,
19,18,17,16,15,14,13};
int Max(int a,int b){
return a>b?a:b;
}
int Min(int a,int b){
return a<b?a:b;
}
int h(int *a){
int i;
int b=0,c=0,d=0;
for(i=0;i<8;i++){
if(a[e[i]]==1)
b++;
else if(a[e[i]]==2)
c++;
else if(a[e[i]]==3)
d++;
}
return 8-Max(b,Max(c,d));
}
void change(int dir,int * tmp){
int i;
if(dir<4){
int temp=tmp[cha[dir][0]];
for(i=1;i<7;i++)
tmp[cha[dir][i-1]]=tmp[cha[dir][i]];
tmp[cha[dir][6]]=temp;
}
else{
int temp=tmp[cha[re[dir]][6]];
for(i=6;i>0;i--)
tmp[cha[re[dir]][i]]=tmp[cha[re[dir]][i-1]];
tmp[cha[re[dir]][0]]=temp;
}
}
int dfs(int * a,int depth,int premove){
int hdepth,i,j;
hdepth=h(a);
if(hdepth+depth>bound)
return hdepth+depth;
if(hdepth==0){
ans=true;
final=a[6];
return depth;
}
int next_bound=1e7;
for(i=0;i<8;i++){
if(re[i]==premove)
continue;
int tmp[30];
for(j=0;j<24;j++)
tmp[j]=a[j];
change(i,tmp);
sol[depth]=i;
int new_bound=dfs(tmp,depth+1,i);
if(ans)
return new_bound;
else
next_bound=Min(new_bound,next_bound);
}
return next_bound;
}
void IDA_STAR(){
memset(sol,0,sizeof(sol));
bound=h(init);
ans=false;
while(!ans && bound<=100){
bound=dfs(init,0,-100);
}
for(int i=0;i<bound;i++)
printf("%c",sol[i]+'A');
printf("\n");
printf("%d\n",final);
}
int main(){
int i,j;
while(scanf("%d",&init[0]) && init[0]!=0){
for(i=1;i<24;i++)
scanf("%d",&init[i]);
if(h(init)==0){
printf("No moves needed\n");
printf("%d\n",init[6]);
continue;
}
IDA_STAR();
}
}