【USACO 3.2.5】魔板
2014-06-29 14:26
316 查看
【描述】
在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有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: msquareINPUT FORMAT:
(file msquare.in)
只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。
OUTPUT FORMAT:
(file msquare.out)
Line 1: 包括一个整数,表示最短操作序列的长度。
Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。
【分析】
直接广搜就行了,然后用哈希判重。#include <cstdlib> #include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> #include <set> #include <queue> #include <vector> using namespace std; struct state { int data[2][5]; int step,parent;//步数 int kind;//表示该状态经过哪一种变换得来 }begin,end;//ren用来记录标号 bool hash[16777216*2]; int sqr[9]; unsigned int point=0,p=0;//rem指针 vector<state>Q; void bfs(); bool check(state a,state b); void init();//初始化 void change(state &t,int type); void print(int t);//打印 int h(state t);//哈希函数 int main() { //文件操作 freopen("msquare.in","r",stdin); freopen("msquare.out","w",stdout); //读入与初始化 for (int i=1;i<=4;i++) {scanf("%d",&end.data[0][i]);begin.data[0][i]=i;} for (int j=4;j>=1;j--) {scanf("%d",&end.data[1][j]);begin.data[1][j]=8-j+1;} if (check(begin,end)) {printf("0");return 0;} bfs(); int temp=Q.size()-1; printf("%d\n",Q[temp].step); print(temp); return 0; } void init() { memset(hash,0,sizeof(hash)); sqr[0]=1; for (int i=1;i<=7;i++) sqr[i]=sqr[i-1]*8; begin.step=0; begin.parent=-1; } void bfs() { Q.push_back(begin); init(); while (point<Q.size()) { state u=Q[point]; state temp=u;//记录 for (int i=1;i<=3;i++) { change(u,i); if (hash[h(u)]==0)//没有加入过 { Q.push_back(u); hash[h(u)]=1; if (check(u,end)) return; }u=temp;//还原 } point++; } } bool check(state a,state b)//比较函数 { for (int i=0;i<=1;i++) for (int j=1;j<=4;j++) if (a.data[i][j]!=b.data[i][j]) return 0; return 1; } void change(state &t,int type) { state temp=t; //初始化 temp.step++; temp.parent=point; temp.kind=type; if (type==1) for (int i=1;i<=4;i++) swap(temp.data[0][i],temp.data[1][i]); else if (type==2) { temp.data[0][1]=t.data[0][4]; temp.data[1][1]=t.data[1][4]; for (int i=2;i<=4;i++) { temp.data[0][i]=t.data[0][i-1]; temp.data[1][i]=t.data[1][i-1]; } } else if (type==3) { temp.data[0][2]=t.data[1][2]; temp.data[0][3]=t.data[0][2]; temp.data[1][3]=t.data[0][3]; temp.data[1][2]=t.data[1][3]; } t=temp; } void print(int t) { if (!t) return; print(Q[t].parent); printf("%c",char(Q[t].kind-1+'A')); ++p; if (p==60) {printf("\n");p=0;}//换行 } int h(state t) { int i,j,ans=0; for (i=0;i<=1;i++) for (j=1;j<=4;j++) ans+=t.data[i][j]*sqr[i*4+j-1]; return ans; }
相关文章推荐
- 【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板
- 【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板
- 【USACO3.2.5】魔板 康托展开/BFS
- usaco3.2.6魔板
- JZOJ1286.【USACO题库】3.2.5 Magic Squares魔板
- 1286. 【USACO题库】3.2.5 Magic Squares魔板 (Standard IO)
- USACO3.2.5 Magic Squares (msquare)
- USACO 3.2 Magic Squares 魔板
- usaco3.2.5饲料调配
- [USACO3.2]魔板 Magic Squares
- USACO 3.2.5 Magic Squares
- USACO/msquare 3.2.5
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- USACO3.2.5-butter
- USACO_3.2_Magic Squares 魔板_BFS_HASH
- USACO3.2.5 Magic Squares (msquare)
- 【USACO题库】3.2.5 Magic Squares魔板
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- USACO 3.2.5 magic square