hdu 1401 Solitaire (双向广搜)
2012-02-23 19:54
267 查看
题意:在8 * 8 的跳棋棋盘上,给你两个状态,每个状态4个点,判断一个状态8步内能否到达另一个状态。
分析:给定了始末状态,很典型的双向广搜。
从始末两个方向进行广度搜索,理想情况下可以减少二分之一的搜索量,从而提高搜索速度。
问题的关键在于状态的保存,因为四个棋子是一样的,棋盘的大小只有8*8,所以先按坐标排序之后,用二进制每三个位保存一个棋子的一个坐标,总共需要24个位。
对双向广度搜索算法的改进:
略微修改一下控制结构,每次while循环时只扩展正反两个方向中节点数目较少的一个,可以使两边的发展速度保持一定的平衡,从而减少总扩展节点的个数,加快搜索速度。
这代码写的有点挫,用俩个BFS写的,不是用同一个的,不过也省了麻烦,第一道双广,调试了一个下午。
View Code
分析:给定了始末状态,很典型的双向广搜。
从始末两个方向进行广度搜索,理想情况下可以减少二分之一的搜索量,从而提高搜索速度。
问题的关键在于状态的保存,因为四个棋子是一样的,棋盘的大小只有8*8,所以先按坐标排序之后,用二进制每三个位保存一个棋子的一个坐标,总共需要24个位。
对双向广度搜索算法的改进:
略微修改一下控制结构,每次while循环时只扩展正反两个方向中节点数目较少的一个,可以使两边的发展速度保持一定的平衡,从而减少总扩展节点的个数,加快搜索速度。
这代码写的有点挫,用俩个BFS写的,不是用同一个的,不过也省了麻烦,第一道双广,调试了一个下午。
View Code
#include<iostream> #include<algorithm> #include<queue> #include<bitset> #define N 8 using namespace std; bitset<20000010> vis1,vis2; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; bool map ,flag; struct point { int x,y; }; struct node { point p[4]; }; node start,end1; queue<node> Q1,Q2; bool cmp(point a,point b) { if(a.x!=b.x) return a.x<b.x; return a.y<b.y; } void get_map(point p[]) { memset(map,0,sizeof(map)); for(int i=0;i<4;i++) map[p[i].x][p[i].y]=1; } int get_hash(point p[]) { sort(p,p+4,cmp); int a=0,j=7; for(int i=0;i<4;i++) { a|=(p[i].x<<(j*3)); a|=(p[i].y<<(j-1)*3); j-=2; } return a; } void BFS1() { int a; int size=Q1.size(); while(size--) { node q=Q1.front(),temp; Q1.pop(); get_map(q.p); for(int i=0;i<4;i++) for(int k=0;k<4;k++) { temp=q; int x=q.p[i].x+dir[k][0]; int y=q.p[i].y+dir[k][1]; if(x<0 ||x>=N || y<0 || y>=N) continue; temp.p[i].x=x; temp.p[i].y=y; if(map[x][y]) { int x1=x+dir[k][0]; int y1=y+dir[k][1]; if(x1<0 || x1>=N || y1<0 || y1>=N || map[x1][y1]) continue; temp.p[i].x=x1;temp.p[i].y=y1; } a=get_hash(temp.p); if(vis1[a]) continue; if(vis2[a]) { flag=true; return ; } vis1[a]=true; Q1.push(temp); } } } void BFS2() { int a; int size=Q2.size(); while(size--) { node q=Q2.front(),temp; Q2.pop(); get_map(q.p); for(int i=0;i<4;i++) for(int k=0;k<4;k++) { temp=q; int x=temp.p[i].x+dir[k][0]; int y=temp.p[i].y+dir[k][1]; if(x<0 ||x>=N || y<0 || y>=N) continue; temp.p[i].x=x; temp.p[i].y=y; if(map[x][y]) { int x1=x+dir[k][0]; int y1=y+dir[k][1]; if(x1<0 || x1>=N || y1<0 || y1>=N || map[x1][y1]) continue; temp.p[i].x=x1;temp.p[i].y=y1; } a=get_hash(temp.p); if(vis2[a]) continue; if(vis1[a]) { flag=true; return ; } vis2[a]=true; Q2.push(temp); } } } int main() { while(scanf("%d %d",&start.p[0].x,&start.p[0].y)==2) { start.p[0].x--; start.p[0].y--; for(int i=1;i<4;i++) { scanf("%d %d",&start.p[i].x,&start.p[i].y); start.p[i].x--;start.p[i].y--; } for(int i=0;i<4;i++) { scanf("%d %d",&end1.p[i].x,&end1.p[i].y); end1.p[i].x--; end1.p[i].y--; } while(!Q1.empty()) Q1.pop(); while(!Q2.empty()) Q2.pop(); vis1.reset(); vis2.reset(); int a; a=get_hash(start.p); vis1[a]=true; int b=get_hash(end1.p); if(a==b) { printf("YES\n"); continue; } vis2[b]=true; Q1.push(start);Q2.push(end1); int step=8; flag=false; while(step--) { if(Q1.size()<=Q2.size()) BFS1(); else BFS2(); if(flag) break; } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- HDU 1401 Solitaire (双向广搜)
- HDU 1401 Solitaire(双向BFS)
- hdu 1401/poj 1198 Solitaire(BFS,剪枝)
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
- hdu 1401 Solitaire 双向bfs
- hdu 1401 zoj1505 pku 1198 双向广搜
- HDU 1401 Solitaire 双向BFS
- hdu 1401 Solitaire(双向bfs)
- HDU 1401 Solitaire
- hdu 1401 Solitaire(双向宽搜)
- HDU 1401 Solitaire (双向搜索)
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
- HDU 1401 Solitaire
- HDU 1401 Solitaire [双向BFS]
- hdu 1401 Solitaire(bfs)
- HDU 1401 Solitaire(棋盘状态BFS)
- HDU 1401 Solitaire 双向BFS
- HDU 1401 Solitaire(双向搜索)
- HDU-1401 Solitaire 搜索
- HDU - 1401 Solitaire