测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A41019. 魔板

填空题 困难

题目描述

魔板

题目描述

在魔方风靡全球之后不久,Rubik先生发明了它的简化版――魔板。魔板 由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方 向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:

1 2 3 4

8 7 6 5

对于魔板,可施加三种不同的操作,具体操作方法如下:

A: 上下两行互换,如上图可变换为状态87654321

B: 每行同时循环右移一格,如上图可变换为41236785

C: 中间4个方块顺时针旋转一格,如上图可变换为17245368

给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。

输入格式

每组测试数据包括两行,分别代表魔板的初态与目态。

输出格式

对每组测试数据输出满足题意的变换步骤。

样例输入

12345678
17245368
12345678
82754631

样例输出

C
AC

参考答案

#include<iostream> #include<cstring> struct { char str[9],opt; int par; }queue[40330],tmp,nxt; int fac[8]={1,1,2,6,24,120,720,5040},vis[40330]; char opt[4]="ABC",aim[9]; void(*fun[3])(char *str); int hash(char *str) { int i,j,cnt,sum=0; for(i=0;i<8;i++) { for(cnt=0,j=i+1;j<8;j++) if(str[j]>str[i]) cnt++; sum+=cnt*fac[7-i]; } if(vis[sum]) return 1; vis[sum]=1; return 0; } void swap(char *a,char *b) { *a+=*b; *b=*a-*b; *a-=*b; return; } void optA(char *str) { swap(&str[0],&str[4]); swap(&str[1],&str[5]); swap(&str[2],&str[6]); swap(&str[3],&str[7]); return; } void optB(char *str) { int i; char tmp; for(tmp=str[3],i=3;i>0;i--) str[i]=str[i-1]; str[0]=tmp; for(tmp=str[7],i=7;i>4;i--) str[i]=str[i-1]; str[4]=tmp; return; } void optC(char *str) { char tmp=str[1]; str[1]=str[5]; str[5]=str[6]; str[6]=str[2]; str[2]=tmp; return; } void print(int k) { if(queue[k].par==-1) return; print(queue[k].par); putchar(queue[k].opt); return; } void bfs() { int front=0,rear=0,i; tmp.opt=0; tmp.par=-1; if(!strcmp(tmp.str,aim)) return; hash(tmp.str); queue[rear++]=tmp; while(front!=rear) { tmp=queue[front]; for(i=0;i<3;i++) { nxt=tmp; (*fun[i])(nxt.str); if(hash(nxt.str)) continue; nxt.opt=opt[i]; nxt.par=front; queue[rear]=nxt; if(!strcmp(nxt.str,aim)) { print(rear); return; } rear++; } front++; } return; } int main() { fun[0]=optA; fun[1]=optB; fun[2]=optC; while(scanf("%s",tmp.str)!=EOF) { std::cin>>aim; swap(&tmp.str[4],&tmp.str[7]); swap(&tmp.str[5],&tmp.str[6]); swap(&aim[4],&aim[7]); swap(&aim[5],&aim[6]); memset(vis,0,sizeof(vis)); bfs(); std::cout<<std::endl; } return 0; }
上一题 下一题