【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\n",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("\n");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 } 

 

posted @ 2014-06-29 14:26  TCtower  阅读(629)  评论(0编辑  收藏  举报