/*
题意:给出一个井字的图案,上面有且只有8个1,8个2,8个3,可以从A~H8个方向拉某行/列,问最少拉多少次使得
中间的8个方格的数字相同
题解:IDA_STAR
关键在实现的方法,通过用一个position的二维数组分别记录4条的对应位置,8个方向搜索,由于每一个点都要记录
当时的情况
注意:往某个方向拉了一格之后,下一层搜索就不应该包含此次的相反方向,避免来回重复搜索;
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
int position[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}; // 分别按照4条方格记录位置
int mark[24]; // 记录图的值
int midpos[8] = {6,7,8,11,12,15,16,17}; // 中间框的位置
int re[8] = {5,4,7,6,1,0,3,2}; // 8个方向对应的反方向
int ans,ansdepth;
char ansstr[10005]; // 最终的字符串
int lstdepth; // IDA_STAR算法时的搜索的深度(不严谨的说法)
int minnum(int *pmark) // 估价函数,求最少还差多少个数可以满足条件
{
int sum1,sum2,sum3;
sum1 = sum2 = sum3 = 0;
for(int i=0; i<8; i++)
{
if (1 == pmark[midpos[i]])
sum1++;
else if (2 == pmark[midpos[i]])
sum2++;
else if (3 == pmark[midpos[i]])
sum3++;
}
int ret = sum1;
if (ret < sum2)
ret = sum2;
if (ret < sum3)
ret = sum3;
return 8 - ret;
}
int dfs(int depth, int *pmark, int predir)
{
int mint = minnum(pmark);
if (depth + mint > lstdepth) // 搜索到lstdepth时回溯
{
return depth + mint;
}
if (mint == 0)
{
ans = pmark[6];
ansdepth = depth;
return depth;
}
int mindepth = 1 << 30; // 每一次都求出后面的结点中最小的估价
for(int i=0; i<8; i++)
{
if (predir == i)
continue;
int tmpmark[24];
for(int j=0; j<24; j++)
tmpmark[j] = pmark[j];
if (i < 4)
{
int t = tmpmark[position[i][0]];
for(int j=1; j<7; j++)
tmpmark[position[i][j-1]] = tmpmark[position[i][j]];
tmpmark[position[i][6]] = t;
}
else
{
int c;
if (4 == i)
c = 1;
else if (5 == i)
c = 0;
else if (6 == i)
c = 3;
else if (7 == i)
c = 2;
int t = tmpmark[position[c][6]];
for(int j=5; j>=0; j--)
tmpmark[position[c][j+1]] = tmpmark[position[c][j]];
tmpmark[position[c][0]] = t;
}
ansstr[depth] = i+'A';
int nextdepth = dfs(depth+1, tmpmark, re[i]);
mindepth = std::min(nextdepth, mindepth);
if (ans)
return 0;
}
return mindepth;
}
int main(void)
{
while (~scanf("%d",&mark[0]) && mark[0])
{
for(int i=1; i<24; i++)
scanf("%d",&mark[i]);
ans = ansdepth = 0;
lstdepth = minnum(mark);
ansstr[0] = 0;
while (ans == 0 && lstdepth <= 100)
{
lstdepth = dfs(0,mark,-1);
}
if (ansdepth == 0)
printf("No moves needed");
else
{
for(int i=0; i<ansdepth; i++)
printf("%c",ansstr[i]);
}
printf("\n%d\n",ans);
}
return 0;
}