bzoj1085 [SCOI2005]骑士精神 【迭代加深搜索】
来源:互联网 发布:手机网络代理软件 编辑:程序博客网 时间:2024/06/16 19:56
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1085
解题思路
很容易想到广搜,但空间会超,而深搜又会超时,所以我们用迭代加深搜索,它比广搜慢,比深搜快,但空间和深搜一样,所以可以接受。
估价函数least(v)表示从当前状态v到目标状态所需的最小步数,显然是还未归位的棋子数减一;
首先枚举所需步数dep,再dfs,若step(v)+least(v)>dep则跳过。
其实迭代加深搜索就是dfs的一种剪枝,这个算法特别擅长处理解的深度不大,但每个搜索局面后继较多,且局面容易进行估价的搜索问题。
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>using namespace std;const char des[5][5]={'1','1','1','1','1', '0','1','1','1','1', '0','0','*','1','1', '0','0','0','0','1', '0','0','0','0','0'};const int fx[8]={-1,-2,-2,-1,1,2,2,1};const int fy[8]={2,1,-1,-2,-2,-1,1,2};char a[5][5];int T,dep,tx,ty;int least(){ int res=-1; for(int i=0;i<5;i++) for(int j=0;j<5;j++) if(a[i][j]!=des[i][j])res++; return res;}bool dfs(int step,int x,int y){ if(step==dep) { if(least()==-1)return true; else return false; } if(step+least()>dep)return false; for(int i=0;i<8;i++) { int dx=x+fx[i],dy=y+fy[i]; if(dx>=0&&dx<5&&dy>=0&&dy<5) { swap(a[x][y],a[dx][dy]); if(dfs(step+1,dx,dy))return true; swap(a[x][y],a[dx][dy]); } } return false;}int main(){ //freopen("lx.in","r",stdin); scanf("%d",&T); while(T--) { for(int i=0;i<5;i++) { scanf("%s",a[i]); for(int j=0;j<5;j++) if(a[i][j]=='*')tx=i,ty=j; } for(dep=0;dep<=15;dep++) if(dfs(0,tx,ty))break; if(dep>15)cout<<-1<<'\n'; else cout<<dep<<'\n'; } return 0;}
也可以用折半搜索做;
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<ctime>#include<map>#define ll unsigned long longusing namespace std;int getint() { int i=0,f=1;char c; for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar()); if(c=='-')c=getchar(),f=-1; for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0'; return i*f;}const int des[5][5]={2,2,2,2,2, 1,2,2,2,2, 1,1,0,2,2, 1,1,1,1,2, 1,1,1,1,1};const int fx[8]={-1,-2,-2,-1,1,2,2,1};const int fy[8]={2,1,-1,-2,-2,-1,1,2};struct node{ int a[5][5]; int x,y,tp,step;};map<ll,int>book[2];queue<node>q;char a[5][5];ll hash(node t){ ll res=0; for(int i=0;i<5;i++) for(int j=0;j<5;j++) res=res*3+t.a[i][j]; return res;}int bfs(node s,node t){ while(!q.empty())q.pop(); book[0].clear(),book[1].clear(); s.tp=0,t.tp=1; s.step=t.step=0; q.push(s),q.push(t); while(!q.empty()) { node x,a; a=q.front(); q.pop(); ll tmp=hash(a); if(book[a.tp^1].count(tmp)) if(book[a.tp^1][tmp]+a.step<=15) return book[a.tp^1][tmp]+a.step; else continue; if(a.step>=8)continue; for(int i=0;i<8;i++) { x=a; x.x+=fx[i],x.y+=fy[i]; if(x.x<0||x.x>=5||x.y<0||x.y>=5)continue; swap(x.a[x.x][x.y],x.a[a.x][a.y]); tmp=hash(x); if(book[x.tp][tmp])continue; book[x.tp][tmp]=++x.step; q.push(x); } } return -1;} int main(){ //freopen("lx.in","r",stdin); node s,t; int T=getint(); while(T--) { for(int i=0;i<5;i++) { scanf("%s",a[i]); for(int j=0;j<5;j++) { if(a[i][j]=='*')s.x=i,s.y=j,s.a[i][j]=0; else s.a[i][j]=a[i][j]-'0'+1; t.a[i][j]=des[i][j]; } } t.x=t.y=2; int ans=bfs(s,t); cout<<ans<<'\n'; } return 0; }
阅读全文
0 0
- bzoj1085 [SCOI2005]骑士精神 【迭代加深搜索】
- 【bzoj1085】【 [SCOI2005]骑士精神】启发式剪枝+迭代加深搜索
- [SCOI2005][BZOJ1085][迭代加深+A*剪枝]骑士精神
- [学习][SCOI2005][bzoj1085]迭代加深 骑士精神
- bzoj1085 [SCOI2005]骑士精神 ( 迭代加深搜索 + A*启发式搜索 )
- BZOJ 1085: [SCOI2005]骑士精神 启发式搜索+迭代加深
- SCOI2005 骑士精神(Knight) 启发式搜索 迭代加深
- 【BZOJ1085】[SCOI2005]骑士精神【搜索】【剪枝】
- [BZOJ1085][SCOI2005]骑士精神
- BZOJ1085 [SCOI2005]骑士精神
- bzoj1085: [SCOI2005]骑士精神
- [BZOJ1085][SCOI2005]骑士精神
- bzoj1085[SCOI2005]骑士精神
- BZOJ1085 [SCOI2005]骑士精神
- 【bzoj1085】[SCOI2005]骑士精神
- [BZOJ1085][SCOI2005]骑士精神
- bzoj1085: [SCOI2005]骑士精神
- 【bzoj1085】[SCOI2005]骑士精神
- 事务处理后执行耗时线程
- python进阶
- 剑指offer-8- Python实现旋转数组的最小数
- 《Handling Cold-Start Problem in Review Spam Detection by Jointly Embedding Texts and Behaviors》阅读笔记
- 快速线性筛选法求素数(质数)
- bzoj1085 [SCOI2005]骑士精神 【迭代加深搜索】
- ES Format 介紹
- hdu1026 BFS+路径保存
- springmvc的contronller之间携带参数的跳转
- Vmware redhat 使用Nat方式上网
- 读书笔记《机器学习》: 第八章:集成学习
- 7. Reverse Integer
- Pecan框架介绍
- 剑指offer_圆圈中最后剩下的数字