魔板
题目背景
在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有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
对于每种可能的状态,这三种基本操作都可以使用。
你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。
输入输出格式
输入格式:
只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。
输出格式:
Line 1: 包括一个整数,表示最短操作序列的长度。
Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。
输入输出样例
输入:
2 6 8 4 5 7 3 1
输出:
7
BCABCCB
分析:
典型的搜索题目,难点就在于如何判重
在这里,判重如果用八进制拆分的话,可能。。。所以我用了康拓展开,
然后结构体储存图,开结构体类型的队列。往结构体里面直接存图,而不是存数,就完美的解决这个问题了。
剩下的就是注意一下细节就可以了。。
1 //其实三种改变方式可以for循环的;; 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<queue> 6 #define ll long long 7 #define dd double 8 using namespace std; 9 const int maxn=4e6+5; 10 int jc[10]={1,2,6,24,120,720,5040,40320}; 11 int k[10],fa[maxn]; 12 bool inq[maxn]; 13 char xl[maxn]; 14 struct cp{ 15 int map[2][4],dis; 16 }sta,end; 17 queue<cp> q; 18 inline int kt(cp x){ 19 int sum=0; 20 memset(k,0,sizeof k); 21 for(int i=0;i<4;i++) k[i]=x.map[0][i],k[7-i]=x.map[1][i]; 22 for(int i=0;i<8;i++){ 23 int s=0; 24 for(int j=i+1;j<8;j++) if(k[j]<k[i]) ++s; 25 sum+=jc[7-i]*s; 26 } 27 return sum; 28 } 29 inline bool judge(cp a){ 30 for(int i=0;i<2;i++) for(int j=0;j<4;j++) 31 if(a.map[i][j]!=end.map[i][j]) return 0; 32 return 1; 33 } 34 inline cp cg_a(cp now){ 35 cp x; 36 for(int i=0;i<4;i++) 37 x.map[0][i]=now.map[1][i],x.map[1][i]=now.map[0][i]; 38 return x; 39 } 40 inline cp cg_b(cp now){ 41 cp x; 42 for(int i=0;i<3;i++) 43 x.map[0][i+1]=now.map[0][i],x.map[1][i+1]=now.map[1][i]; 44 x.map[0][0]=now.map[0][3],x.map[1][0]=now.map[1][3]; 45 return x; 46 } 47 inline cp cg_c(cp now){ 48 cp x; 49 for(int i=0;i<2;i++) 50 x.map[i][0]=now.map[i][0],x.map[i][3]=now.map[i][3]; 51 x.map[0][1]=now.map[1][1], 52 x.map[0][2]=now.map[0][1], 53 x.map[1][1]=now.map[1][2], 54 x.map[1][2]=now.map[0][2]; 55 return x; 56 } 57 void print(int x){ 58 if(x) print(fa[x]); 59 if(xl[x]) printf("%c",xl[x]); 60 } 61 void bfs(cp x){ 62 if(judge(x)){ 63 printf("0\n"); 64 exit(0); 65 } 66 x.dis=0,q.push(x); 67 inq[kt(x)]=1; 68 while(!q.empty()){ 69 x=q.front();q.pop(); 70 cp now_a=cg_a(x),now_b=cg_b(x),now_c=cg_c(x); 71 int kt_a=kt(now_a),kt_b=kt(now_b),kt_c=kt(now_c),kt_x=kt(x); 72 73 if(!inq[kt_a]) inq[kt_a]=1,now_a.dis=x.dis+1,q.push(now_a),fa[kt_a]=kt_x,xl[kt_a]='A'; 74 if(!inq[kt_b]) inq[kt_b]=1,now_b.dis=x.dis+1,q.push(now_b),fa[kt_b]=kt_x,xl[kt_b]='B'; 75 if(!inq[kt_c]) inq[kt_c]=1,now_c.dis=x.dis+1,q.push(now_c),fa[kt_c]=kt_x,xl[kt_c]='C'; 76 77 if(judge(now_a)){ 78 printf("%d\n",now_a.dis); 79 print(kt_a); 80 exit(0); 81 } 82 if(judge(now_b)){ 83 printf("%d\n",now_b.dis); 84 print(kt_b); 85 exit(0); 86 } 87 if(judge(now_c)){ 88 printf("%d\n",now_c.dis); 89 print(kt_c); 90 exit(0); 91 } 92 } 93 } 94 inline int read(){ 95 char ch=getchar(); 96 int x=0,f=1; 97 while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} 98 while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar(); 99 return x*f; 100 } 101 int main(){ 102 for(int i=0;i<4;i++) sta.map[0][i]=1+i; 103 for(int i=0;i<4;i++) sta.map[1][i]=8-i; 104 for(int i=0;i<4;i++) end.map[0][i]=read(); 105 for(int i=3;i>=0;i--) end.map[1][i]=read(); 106 bfs(sta); 107 return 0; 108 }