• 魔板


    题目背景

      在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有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
    ");
     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
    ",now_a.dis);
     79             print(kt_a);
     80             exit(0);
     81         }
     82         if(judge(now_b)){
     83             printf("%d
    ",now_b.dis);
     84             print(kt_b);
     85             exit(0);
     86         }
     87         if(judge(now_c)){
     88             printf("%d
    ",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 }
    代码(写丑了)
  • 相关阅读:
    SpringMvc执行流程
    Lock wait timeout exceeded; try restarting transaction解决方法
    MySQL删除复杂的重复数据的解决方案(一条数据项中包含多个值的情况)
    数据移植时递归运算查询部门及其下级所有部门的问题
    IDEA常用插件
    mybatis和mybatisPlus中解决实体类字段与数据库关键字冲突问题
    时间日期操作
    spring项目中使用MD5加密方式
    idea如何调出仪表盘
    scanf使用过程中的技巧与坑位
  • 原文地址:https://www.cnblogs.com/RisingGods/p/9688538.html
Copyright © 2020-2023  润新知