【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 } 

【USACO 3.2.5】魔板

时间: 2024-08-01 23:33:17

【USACO 3.2.5】魔板的相关文章

洛谷 P2730 魔板 Magic Squares

P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母“

洛谷P2730 魔板 Magic Squares

P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母“

Luogu P2730 魔板 Magic Squares

P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母"

hdu1430魔板(广搜+康托展开+string应用)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2420    Accepted Submission(s): 511 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

hdu 魔板

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack

ACM-康托展开+预处理BFS之魔板——hdu1430

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1679    Accepted Submission(s): 354 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

BFS [HDU 1430] 魔板

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1988    Accepted Submission(s): 407 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

【判重+广搜(bfs)】魔板

判重+广搜(bfs)]魔板 Time Limit: 1000MS Memory Limit: 32768KB Special Judge 有一个两行四列的魔板,每个格子里有一个1到8的数字(数字唯一),现在我们可以对魔板进行以下操作: 1.交换两行的数字. 2.将第一列移到第二列,第二列到第三列,第三列到第四列,第四列到第一列. 3.将中间四个数顺时针转一次. 现给你初始状态,我末状态请你用最小的步数将它从初始状态变到末状态. 输入: 前两行,每行4个数表示初状态. 后两行,每行4个数表示末状态