zoukankan      html  css  js  c++  java
  • 【USACO 3.2.5】魔板

    【描述】

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

    【分析】

    直接广搜就行了,然后用哈希判重。

      1 #include <cstdlib> 
      2 #include <iostream> 
      3 #include <cmath> 
      4 #include <cstdio> 
      5 #include <cstring> 
      6 #include <algorithm> 
      7 #include <set>  
      8 #include <queue> 
      9 #include <vector>
     10 using namespace std; 
     11 struct state 
     12 { 
     13        int data[2][5]; 
     14        int step,parent;//步数  
     15        int kind;//表示该状态经过哪一种变换得来  
     16 }begin,end;//ren用来记录标号  
     17 bool hash[16777216*2]; 
     18 int sqr[9];
     19 unsigned int point=0,p=0;//rem指针  
     20 vector<state>Q; 
     21 
     22 void bfs(); 
     23 bool check(state a,state b); 
     24 void init();//初始化  
     25 void change(state &t,int type); 
     26 void print(int t);//打印  
     27 int h(state t);//哈希函数  
     28   
     29 int main() 
     30 { 
     31     //文件操作 
     32     freopen("msquare.in","r",stdin); 
     33     freopen("msquare.out","w",stdout);  
     34     //读入与初始化  
     35     for (int i=1;i<=4;i++) {scanf("%d",&end.data[0][i]);begin.data[0][i]=i;} 
     36     for (int j=4;j>=1;j--) {scanf("%d",&end.data[1][j]);begin.data[1][j]=8-j+1;} 
     37     if (check(begin,end)) {printf("0");return 0;}
     38     bfs(); int temp=Q.size()-1;
     39     printf("%d
    ",Q[temp].step); 
     40     print(temp); 
     41     return 0; 
     42 } 
     43 void init() 
     44 { 
     45      memset(hash,0,sizeof(hash)); 
     46      sqr[0]=1;
     47      for (int i=1;i<=7;i++) sqr[i]=sqr[i-1]*8;
     48      begin.step=0; 
     49      begin.parent=-1; 
     50 }  
     51 void bfs() 
     52 { 
     53      Q.push_back(begin); 
     54      init();  
     55      while (point<Q.size()) 
     56      { 
     57            state u=Q[point];
     58            state temp=u;//记录  
     59            
     60            for (int i=1;i<=3;i++) 
     61            { 
     62                change(u,i); 
     63                if (hash[h(u)]==0)//没有加入过 
     64                { 
     65                    Q.push_back(u);
     66                    hash[h(u)]=1;
     67                    if (check(u,end)) return;
     68                }u=temp;//还原  
     69            } 
     70            point++;
     71      }  
     72 } 
     73 bool check(state a,state b)//比较函数  
     74 { 
     75      for (int i=0;i<=1;i++) 
     76      for (int j=1;j<=4;j++) if (a.data[i][j]!=b.data[i][j]) return 0; 
     77      return 1; 
     78 } 
     79 void change(state &t,int type) 
     80 { 
     81      state temp=t; 
     82      //初始化 
     83      temp.step++; 
     84      temp.parent=point; 
     85      temp.kind=type; 
     86      if (type==1) for (int i=1;i<=4;i++) swap(temp.data[0][i],temp.data[1][i]); 
     87      else if (type==2) 
     88      { 
     89           temp.data[0][1]=t.data[0][4]; 
     90           temp.data[1][1]=t.data[1][4]; 
     91           for (int i=2;i<=4;i++) 
     92           { 
     93               temp.data[0][i]=t.data[0][i-1]; 
     94               temp.data[1][i]=t.data[1][i-1]; 
     95           } 
     96      }  
     97      else if (type==3) 
     98      { 
     99           temp.data[0][2]=t.data[1][2]; 
    100           temp.data[0][3]=t.data[0][2]; 
    101           temp.data[1][3]=t.data[0][3]; 
    102           temp.data[1][2]=t.data[1][3]; 
    103      } 
    104      t=temp; 
    105 } 
    106 void print(int t) 
    107 { 
    108      if (!t) return; 
    109      print(Q[t].parent); 
    110      printf("%c",char(Q[t].kind-1+'A'));
    111      ++p; 
    112      if (p==60) {printf("
    ");p=0;}//换行  
    113 } 
    114 int h(state t) 
    115 { 
    116     int  i,j,ans=0; 
    117     for (i=0;i<=1;i++) 
    118     for (j=1;j<=4;j++) ans+=t.data[i][j]*sqr[i*4+j-1];
    119     return ans; 
    120 } 
  • 相关阅读:
    二叉树的存储结构
    面试Java需要的知识总结
    EJB总结
    WEB 容器、WEB服务和应用服务器的区别与联系
    Linux安装JBOSS
    JBOSS和WebLogic区别
    深入浅出JMS(一)--JMS基本概念
    Java缓冲流细节
    xor和路径(codevs 2412)
    外星千足虫(bzoj 1923)
  • 原文地址:https://www.cnblogs.com/hoskey/p/3815060.html
Copyright © 2011-2022 走看看