SSL-ZYC 1692 魔板
2018-03-07 15:51
309 查看
题目大意:
对于一个2*4的魔板,你有三种操作:
A 交换上下两行
B 将最右边的一列插入最左边
C 魔板中央四格作顺时针旋转
已知
为魔板复原的样子,现在给出一个魔板,要求输出复原的最少步数以及依次进行的操作。
思路
这道题我听地真的很懵。。。
正解是BFS+HASH,从复原的样子开始搜索,把三种变化方法都搜一遍,直到成为了输入的样子(此时的方案绝对是最优方案),然后递归输出。
代码:
对于一个2*4的魔板,你有三种操作:
A 交换上下两行
B 将最右边的一列插入最左边
C 魔板中央四格作顺时针旋转
已知
1234 8765
为魔板复原的样子,现在给出一个魔板,要求输出复原的最少步数以及依次进行的操作。
思路
这道题我听地真的很懵。。。
正解是BFS+HASH,从复原的样子开始搜索,把三种变化方法都搜一遍,直到成为了输入的样子(此时的方案绝对是最优方案),然后递归输出。
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int k=40319; int c[4][9],sum,x,father[k],ha[k],way[k],head,state[k][9],tail; char a[k][9],b[k]; void csh() //初始化 { c[1][1]=8; c[1][2]=7; c[1][3]=6; c[1][4]=5; c[1][5]=4; c[1][6]=3; c[1][7]=2; c[1][8]=1; c[2][1]=4; c[2][2]=1; c[2][3]=2; c[2][4]=3; c[2][5]=6; c[2][6]=7; c[2][7]=8; c[2][8]=5; c[3][1]=1; c[3][2]=7; c[3][3]=2; c[3][4]=4; c[3][5]=5; c[3][6]=3; c[3][7]=6; c[3][8]=8; //所有变化情况 } int h(int x) //哈希函数 { return x%k; } int locate(int x) //查找 { int m=0; for (int i=1;i<=8;i++) m=m*10+state[x][i]; //取出该情况 int t=h(m); //求出储存位置 int i=0; while (i<k&&ha[(i+t)%k]!=m&&ha[(i+t)%k]!=0) i++; //找到一个符合的情况才退出 if (ha[(i+t)%k]==m) return 1; //如果查找到(即这种情况已经用更少步的方法得到就返回1) else { ha[(i+t)%k]=m; //储存 return 0; //返回0 } } void print(int x) //递归输出 { if (x==1) return; //已经无法递归的话就返回 sum++; //计数 if (way[x]==1) b[sum]='A'; if (way[x]==2) b[sum]='B'; if (way[x]==3) b[sum]='C'; //判断 print(father[x]); //递归 } void bfs() { head=0; tail=1; father[1]=0; way[1]=0; for (int i=1;i<=8;i++) state[1][i]=i; //初始化 do { head++; for (int i=1;i<=3;i++) //枚举每种变化 { tail++; way[tail]=i; //记录路径 father[tail]=head; //记录父节点 for (int j=1;j<=8;j++) state[tail][j]=state[head][c[i][j]]; //更改魔板情况 tail-=locate(tail); //等于 if (locate(tail)==1) tail--; int ok=0; for (int i=1;i<=8;i++) //判断是否已经完成 if (state[tail][i]!=state[0][i]) { ok=1; break; } if (ok==0) { print(tail); //输出 tail=-1; return; } } } while (head<tail); } int main() { csh(); int o=0; for (int i=1;i<=8;i++) { scanf("%d",&state[0][i]); o=o*10+state[0][i]; } if (o==12345678) //特殊判断 { printf("0\n\n"); return 0; } bfs(); printf("%d\n",sum); for (int i=sum;i>=1;i--) { putchar(b[i]); if (i%60==0) printf("\n"); } return 0; }
相关文章推荐
- ssl1692-魔板【HSAH,bfs】
- 洛谷 2730 SSL 1692 魔板
- USACO 3.2 Magic Squares 魔板 ssl 1692 BFS-HASH
- SSL_1692 魔板
- SSL-ZYC 洛谷P1434 滑雪
- SSL-ZYC 堆箱子
- SSL-ZYC 2576 平台
- SSL-ZYC 作业
- SSL-ZYC 牛车
- SSL-ZYC 2406 约数
- SSL-ZYC 1614 医院设置
- SSL-ZYC 小麦高度
- SSL-ZYC 危险系数
- SSL-ZYC 2344 刻录光盘
- SSL-ZYC 2408 比萨
- SSL-ZYC 手机
- SSL-ZYC 懒惰的奶牛①
- SSL-ZYC 方案数
- SSL-ZYC 前缀转后缀
- SSL-ZYC 1624 小萨的烦恼