zoukankan      html  css  js  c++  java
  • 【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板

    题面

    Description

    在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有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

    对于每种可能的状态,这三种基本操作都可以使用。

    你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。

    Input

    只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。

    Output

    Line 1: 包括一个整数,表示最短操作序列的长度。

    Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。

    Sample Input

    2 6 8 4 5 7 3 1

    Sample Output

    7
    BCABCCB

    题解

    看到题目,很容易就可以想到使用BFS
    而状态最多只有8!中,不到50000
    完全可以使用数组直接存储
    但是我用的是状压(有点麻烦自己。。。。)
    然后使用map判重(用康托展开也可以的)
    用了STL效率偏低
    但是能够AC
    其中一定要注意顺序和编号的问题(细节!)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<algorithm>
    using namespace std;
    struct Node
    {
    	  int st;//步数
    	  int t;//状态
    	  int ff;//父节点
    	  char way;//方式 
    }Q[50000];
    int h,t;
    int End,Beg=12348765;
    //bool vis[50000];
    map<int,bool> vis;
    inline int read()
    {
    	   register int x=0,t=1;register char ch=getchar();
    	   while(ch<'0'||ch>'9')ch=getchar();
    	   while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    	   return x;
    }
    int ten[8]={1,10,100,1000,10000,100000,1000000,10000000};
    int change(int tt,int x,int y)//交换状态tt的x位和y位
    {
    	    int ttt=tt,a,b;
    	    for(int i=1;i<x;++i)
    	       ttt/=10;
    	    a=ttt%10;
    	    for(int i=x;i<y;++i)
    	       ttt/=10;
    	    b=ttt%10;
    	    return tt-(a-b)*ten[x-1]+(a-b)*ten[y-1];
    }
    void outp(int t)
    {
    	    vector<Node> Ans;
    	    while(t!=1)
    	    {
    	    	   Ans.push_back(Q[t]);
    	    	   t=Q[t].ff;
    	    }
    	    int si=Ans.size();
    	    cout<<si<<endl;
    	    for(int i=0;i<si;++i)
    	    {
    	         cout<<Ans[si-i-1].way;
    	         if(i%60==59)cout<<endl;
    	    }
    }
    int main()
    {
     	    for(int i=8;i>=5;--i)
     	       End+=(read()*ten[i-1]);
     	    for(int i=1;i<=4;++i)
     	       End+=(read()*ten[i-1]);
     	    Q[1]=(Node){0,Beg,0,0};
     	    if(Beg==End)//初始时相同
    	    {
    	    	     printf("0
    ");
    	    	     return 0;
    	    }
    	    vis[Beg]=true;
    	    h=0,t=1;
    	    while(h<t)
    	    {
    	    	     Node now=Q[++h];
    	    	     int s;
    	    	     //变化A
    				 s=now.t;
    				 for(int i=1;i<=4;++i)
    				    s=change(s,i,i+4);//上下交换
    				 if(vis.find(s)==vis.end())//没有访问过
    				 {
    				 	     vis[s]=true;
    				 	     Q[++t]=(Node){now.st+1,s,h,'A'};
    				 }
    				 if(s==End)
    				 {
    				 	     outp(t);
    				 	     return 0;
    				 }				
    				 //变化B
    				 s=now.t;
    				 for(int i=1;i<=3;++i)
    				    s=change(s,i,i+1);
    				 for(int i=5;i<=7;++i)
    				    s=change(s,i,i+1);
    				 if(vis.find(s)==vis.end())
    				 {
    				 	     vis[s]=true;
    				 	     Q[++t]=(Node){now.st+1,s,h,'B'};
    				 }
    				 if(s==End)
    				 {
    				 	     outp(t);
    				 	     return 0;
    				 }		
    				 //变化C
    				 s=now.t; 
    				 s=change(s,2,3);
    				 s=change(s,2,7);
    				 s=change(s,2,6);
    				 if(vis.find(s)==vis.end())
    				 {
    				 	     vis[s]=true;
    				 	     Q[++t]=(Node){now.st+1,s,h,'C'};
    				 }
    				 if(s==End)
    				 {
    				 	     outp(t);
    				 	     return 0;
    				 }		
    	    }
    	    return 0;
    }
    
  • 相关阅读:
    sql 删除重复行
    sql 内连接和外链接
    浏览器内核
    asp.net session
    使用powerdesigner创建数据库表
    数据库中char, varchar, nvarchar的差异
    概要设计和详细设计说明书的区别
    2.类和对象
    1.Basic Layouts
    1.初学c++,比较困惑的问题。
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7197284.html
Copyright © 2011-2022 走看看