hdu5012 Dice(分治限界法)
2015-08-28 13:14
399 查看
题目链接:点击打开链接
题意描述:给定一个立方体,有上、下、左、右、前、后,初始时在这6个面上分布1~6之间,每个数出现且仅出现一次,然后给定末状态,问最少能在几步之内通过旋转得到末状态?旋转操作具体见题意
解题思路:广搜+剪枝
1、首先由于题目要求是求的最少的步数,我们可以考虑使用广搜
2、对于按某个方向旋转,最多旋转三次,第四次旋转将回到原点,所以我们可以枚举所有情况:每个方向最多旋转三次
同时,骰子还有一个特点,对任意状态最多旋转四次,如果旋转超过四次还没有达到目标,则一定不可能成功旋转,这可以作为
一个强有力的剪枝
3、同时可以声明一个七维的数组vis[7][7][7][7][7][7][7]标记是否已经访问过,不过这题任选2、3中的任意一种剪枝都可以过
代码:
题意描述:给定一个立方体,有上、下、左、右、前、后,初始时在这6个面上分布1~6之间,每个数出现且仅出现一次,然后给定末状态,问最少能在几步之内通过旋转得到末状态?旋转操作具体见题意
解题思路:广搜+剪枝
1、首先由于题目要求是求的最少的步数,我们可以考虑使用广搜
2、对于按某个方向旋转,最多旋转三次,第四次旋转将回到原点,所以我们可以枚举所有情况:每个方向最多旋转三次
同时,骰子还有一个特点,对任意状态最多旋转四次,如果旋转超过四次还没有达到目标,则一定不可能成功旋转,这可以作为
一个强有力的剪枝
3、同时可以声明一个七维的数组vis[7][7][7][7][7][7][7]标记是否已经访问过,不过这题任选2、3中的任意一种剪枝都可以过
代码:
#include <cstdio> #include <queue> #define INF 1e9+7 using namespace std; int a[6],b[6]; int t[6]; struct node { int flag[6]; int a,b,c,d; int ct; bool operator<(const node& o)const { return ct>o.ct; } }; priority_queue<node> pq; bool isequal(int *x) { for(int i=0; i<6; i++) if(x[i]!=b[i]) return false; return true; } void op1(int *x,int *y) { y[0]=x[2]; y[1]=x[3]; y[2]=x[1]; y[3]=x[0]; y[4]=x[4]; y[5]=x[5]; } void op2(int *x,int *y) { y[0]=x[3]; y[1]=x[2]; y[2]=x[0]; y[3]=x[1]; y[4]=x[4]; y[5]=x[5]; } void op3(int *x,int *y) { y[0]=x[4]; y[1]=x[5]; y[2]=x[2]; y[3]=x[3]; y[4]=x[1]; y[5]=x[0]; } void op4(int *x,int *y) { y[0]=x[5]; y[1]=x[4]; y[2]=x[2]; y[3]=x[3]; y[4]=x[0]; y[5]=x[1]; } int bfs() { while(!pq.empty()) pq.pop(); node tmp; tmp.a=3; tmp.b=3; tmp.c=3; tmp.d=3; tmp.ct=0; for(int i=0; i<6; i++) tmp.flag[i]=a[i]; pq.push(tmp); while(!pq.empty()) { node cnode=pq.top(); pq.pop(); if(cnode.ct>4) return -1; if(isequal(cnode.flag)) return cnode.ct; else { if(cnode.a>0) { tmp.a=cnode.a-1; tmp.b=cnode.b; tmp.c=cnode.c; tmp.d=cnode.d; op1(cnode.flag,tmp.flag); tmp.ct=cnode.ct+1; pq.push(tmp); } if(cnode.b>0) { tmp.a=cnode.a; tmp.b=cnode.b-1; tmp.c=cnode.c; tmp.d=cnode.d; op2(cnode.flag,tmp.flag); tmp.ct=cnode.ct+1; pq.push(tmp); } if(cnode.c>0) { tmp.a=cnode.a; tmp.b=cnode.b; tmp.c=cnode.c-1; tmp.d=cnode.d; op3(cnode.flag,tmp.flag); tmp.ct=cnode.ct+1; pq.push(tmp); } if(cnode.d>0) { tmp.a=cnode.a; tmp.b=cnode.b; tmp.c=cnode.c; tmp.d=cnode.d-1; op4(cnode.flag,tmp.flag); tmp.ct=cnode.ct+1; pq.push(tmp); } } } return -1; } int main() { while(scanf("%d",&a[0])!=EOF) { for(int i=1; i<6; ++i) scanf("%d",&a[i]); for(int i=0; i<6; ++i) scanf("%d",&b[i]); printf("%d\n",bfs()); } return 0; }
相关文章推荐
- 设计模式---策略模式
- monkeytalk特殊命令
- Universal Image Loader使用文档
- 使用java理解程序逻辑,变量
- Android 使用url获取数据时的文字编码问题
- 时间单位换算
- 滑雪
- 为什么有的程序员极度推崇 Vim 和 Emacs,却对 IDE 嗤之以鼻?
- JAR、WAR、EAR的使用和区别
- yum 安装lamp环境
- otto源码分析
- HDU3639Hawk-and-Chicken (好题,强连通缩点,建图,DFS回溯)
- meta-data in the Android
- SVN (TortioseSVN) 版本控制之忽略路径(如bin、obj、gen)
- SQL SERVER数据库新认识的一些基础知识
- hadoop集群HA模式的切换尝试初识
- 使用list和tuple
- web压力测试工具 压力测试 webbench
- UVALive 3664 Guess(贪心+精度)
- Java Socket例程3 UDP