h函数用的是8-中间8个位置出现最多的数的个数
刚开始没注意到字典序wa了一发
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
int c1[7]={0,2,6,11,15,20,22},
c2[7]={1,3,8,12,17,21,23},
r1[7]={4,5,6,7,8,9,10},
r2[7]={13,14,15,16,17,18,19},
mid[8]={6,7,8,11,12,15,16,17};
char indexs[9]="ABCDGHEF";
int sp[8]={0,1,2,3,6,7,4,5};
int arr[24];
int h(int s[])
{
int res=0;
for(int k=1;k<4;k++)
{
int tmp=0;
for(int i=0;i<8;i++)
if(s[mid[i]]==k) tmp++;
res=max(tmp,res);
}
return 8-res;
}
int pathLt;
char path[4313240];
bool IDA(int cur[],int len,int pre)
{
if(len>=pathLt){
if(h(cur)) return false;
else {
path[len]='\0';
puts(path);
printf("%d\n",cur[mid[0]] );
return true;
}
}
int next[24];
for(int k=0;k<8;k++)
{
int i=sp[k];//将ABCDEFGH转化为ABCDGHEF对应的坐标
if(i+pre==7) continue;//与上一次移动方向相反
for(int j=0;j<24;j++) next[j]=cur[j];
int tmp;
switch(i)
{
case 0: tmp=next[c1[0]];//A
for(int j=0;j<6;j++)
next[c1[j]]=next[c1[j+1]];
next[c1[6]]=tmp;
break;
case 1: tmp=next[c2[0]];//B
for(int j=0;j<6;j++)
next[c2[j]]=next[c2[j+1]];
next[c2[6]]=tmp;
break;
case 2: tmp=next[r1[6]];//C
for(int j=6;j>0;j--)
next[r1[j]]=next[r1[j-1]];
next[r1[0]]=tmp;
break;
case 3: tmp=next[r2[6]];//D
for(int j=6;j>0;j--)
next[r2[j]]=next[r2[j-1]];
next[r2[0]]=tmp;
break;
case 4: tmp=next[r2[0]];//G
for(int j=0;j<6;j++)
next[r2[j]]=next[r2[j+1]];
next[r2[6]]=tmp;
break;
case 5: tmp=next[r1[0]];//H
for(int j=0;j<6;j++)
next[r1[j]]=next[r1[j+1]];
next[r1[6]]=tmp;
break;
case 6: tmp=next[c2[6]];//E
for(int j=6;j>0;j--)
next[c2[j]]=next[c2[j-1]];
next[c2[0]]=tmp;
break;
case 7: tmp=next[c1[6]];//F
for(int j=6;j>0;j--)
next[c1[j]]=next[c1[j-1]];
next[c1[0]]=tmp;
break;
}
path[len]=indexs[i];
if(len+h(next)<pathLt&&IDA(next,len+1,i))
return true;
}
return false;
}
int main(int argc, char const *argv[])
{
while(scanf("%d",arr)!=EOF&&arr[0])
{
for(int i=1;i<24;i++)
scanf("%d",arr+i);
pathLt=h(arr);
if(!pathLt) {
puts("No moves needed");
printf("%d\n",arr[mid[0]]);
continue;
}
while(!IDA(arr,0,-1)) pathLt++;
}
return 0;
}
/*
1 1 1 1 3 2 2 2 2 1 3 2 2 3 1 2 2 2 3 1 2 1 3 3
1 1 1 1 3 2 3 2 3 1 3 2 2 3 1 2 2 2 3 1 2 1 3 3
1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3
0
*/