在成功地发明了魔方之后,拉比克先生发明了它的二维版本,称作魔板。这是一张有8个大小相同的格子的魔板:
1 2 3 4
8 7 6 5
我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。这是基本状态。
这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态):
“A”:交换上下两行;
“B”:将最右边的一列插入最左边;
“C”:魔板中央作顺时针旋转。
下面是对基本状态进行操作的示范:
A: 8 7 6 5
1 2 3 4
B: 4 1 2 3
5 8 7 6
C: 1 7 2 4
8 6 3 5
对于每种可能的状态,这三种基本操作都可以使用。
你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。
格式
PROGRAM NAME: msquare
INPUT FORMAT:
(file msquare.in)
只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间),表示目标状态。
OUTPUT FORMAT:
(file msquare.out)
Line 1: 包括一个整数,表示最短操作序列的长度。
Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。
SAMPLE INPUT
2 6 8 4 5 7 3 1
SAMPLE OUTPUT
7
BCABCCB
【参考程序】:
/*
ID: XIONGNA1
PROG: msquare
LANG: C++
*/
#include<iostream>
#include<cstring>
using namespace std;
struct node
{
int a[9];
int x,dep;
char c;
} list[40321];//8!
int f[9];
bool hash[40321];
int make(int now)
{//康托展开
bool bo[9]; int sum=0,k;
memset(bo,false,sizeof(bo));
for (int i=1;i<=8;i++)
{
bo[list[now].a[i]]=true;
k=0;
for (int j=1;j<=list[now].a[i]-1;j++)
if (!bo[j]) k++;
sum+=k*f[8-i];
}
return sum+1;
}
void printf_path(int now,int ans)
{
if (list[now].dep==now)
{
printf("%d\n",ans);
return ;
}
printf_path(list[now].dep,ans+1);
printf("%c",list[now].c);
}
int main()
{
freopen("msquare.in","r",stdin);
freopen("msquare.out","w",stdout);
f[0]=1;
for (int i=1;i<=8;i++) f[i]=f[i-1]*i;
for (int i=1;i<=8;i++) scanf("%d",&list[0].a[i]);
memset(hash,false,sizeof(hash));
hash[1]=true;
for (int i=1;i<=8;i++) list[1].a[i]=i;
list[1].x=1; list[1].dep=1; list[1].c=' ';
list[0].x=make(0);
if (list[0].x==list[1].x) printf("0\n");
else
{
int head=1,tail=1;
while (head<=tail)
{
tail++; list[tail].c='A';
list[tail].a[1]=list[head].a[8]; list[tail].a[2]=list[head].a[7];
list[tail].a[3]=list[head].a[6]; list[tail].a[4]=list[head].a[5];
list[tail].a[5]=list[head].a[4]; list[tail].a[6]=list[head].a[3];
list[tail].a[7]=list[head].a[2]; list[tail].a[8]=list[head].a[1];
//for (int i=1;i<=8;i++) list[tail].a[i]=list[head].a[8-i+1];
list[tail].dep=head;
list[tail].x=make(tail);
if (hash[list[tail].x]) tail--;
else
{
hash[list[tail].x]=true;
if (list[tail].x==list[0].x) break;
}
tail++; list[tail].c='B';
list[tail].a[1]=list[head].a[4]; list[tail].a[2]=list[head].a[1];
list[tail].a[3]=list[head].a[2]; list[tail].a[4]=list[head].a[3];
list[tail].a[5]=list[head].a[6]; list[tail].a[6]=list[head].a[7];
list[tail].a[7]=list[head].a[8]; list[tail].a[8]=list[head].a[5];
list[tail].dep=head;
list[tail].x=make(tail);
if (hash[list[tail].x]) tail--;
else
{
hash[list[tail].x]=true;
if (list[tail].x==list[0].x) break;
}
tail++; list[tail].c='C';
list[tail].a[1]=list[head].a[1]; list[tail].a[2]=list[head].a[7];
list[tail].a[3]=list[head].a[2]; list[tail].a[4]=list[head].a[4];
list[tail].a[5]=list[head].a[5]; list[tail].a[6]=list[head].a[3];
list[tail].a[7]=list[head].a[6]; list[tail].a[8]=list[head].a[8];
list[tail].dep=head;
list[tail].x=make(tail);
if (hash[list[tail].x]) tail--;
else
{
hash[list[tail].x]=true;
if (list[tail].x==list[0].x) break;
}
head++;
}
printf_path(tail,0);
}
printf("\n");
return 0;
}