HDU 6171 Admiral (DFS + 剪枝)
来源:互联网 发布:天干地支年算法 编辑:程序博客网 时间:2024/05/17 23:11
题意:
给出原始阵列
0
1 1
2 2 2
3 3 3 3
4 4 4 4 4
5 5 5 5 5 5
问对于给出的某种阵列,能否通过每步只移动 0 至(i - 1 , j)or ( i - 1 , j - 1) or ( i + 1 , j ) or ( i + 1 , j + 1 ) ,在20步之内移动到原始阵列。
思路:
考虑到只要求20步,直接搜索即可。
但 4 ^ 20 一定会 TLE 。考虑剪枝
显然的剪枝是,对于任意局面。
当且仅当 剩余步数 + 1 >= 非法位置的个数 时,有可行解
交上去仍然TLE
考虑到没有状态去重
但由于移动步伐诡异,剪去原地摩擦的情况就能得到很好的效果。
故对父节点做了访问去重。
貌似是数据较水的原因15MS水过。
正解是双向BFS O(4^10 * hash_status)
代码:
#include <bits/stdc++.h>using namespace std;int a[10][10],T,stx,sty;int dirx[]={-1,-1,1,1};int diry[]={-1,0,0,1};int ans;void dfs(int x,int y,int step,int left,int fax,int fay){ if(step>=ans||(ans-step)+1<left) return ;//剪枝1 if(left==0){ ans=step; return ; } for(int i=0;i<4;i++){ int xx=x+dirx[i],yy=y+diry[i]; if(xx>=1&&xx<=6&&yy>=1&&yy<=xx){ if(xx==fax&&yy==fay) continue;//剪枝2 (原地摩擦的情况) int shift=0; int num=a[xx][yy]; if(num==xx) shift++; else if(x==num) shift--; if(x==1) shift++; else if(xx==1) shift--; swap(a[x][y],a[xx][yy]); dfs(xx,yy,step+1,left+shift,x,y); swap(a[x][y],a[xx][yy]); } } return ;}int main(){ //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--){ int left=0; for(int i=1;i<=6;i++){ for(int j=1;j<=i;j++){ scanf("%d",&a[i][j]);a[i][j]++; if(a[i][j]==1){ stx=i;sty=j; } if(a[i][j]!=i) left++; } } ans=21; dfs(stx,sty,0,left,0,0); if(ans==21){ puts("too difficult"); }else printf("%d\n",ans); }}
阅读全文
0 0
- HDU 6171 Admiral (DFS + 剪枝)
- HDU 6171 Admiral
- DFS 剪枝 hdu 1010
- HDU 1010 DFS+剪枝
- hdu 1445 dfs剪枝
- hdu 1010 DFS + 剪枝
- hdu 1010 dfs+剪枝
- HDU 5113 DFS + 剪枝
- hdu 1010(dfs+剪枝)
- hdu 1010(dfs+剪枝)
- HDU 1010 DFS+剪枝
- hdu 1010 DFS+剪枝
- hdu-1455 dfs+剪枝
- Admiral HDU
- HDU 6171 Admiral [双向bfs+hash]
- HDU 6171 Admiral(双向宽搜)
- hdu 6171 Admiral 双向bfs+hash
- hdu oj 1010 dfs+剪枝
- Koa2 学习笔记(第五天)
- CodeForces Sorting by Subsequences
- Jquey Deferred 独立实现版本不依赖jquery
- (六)懒加载和依赖注入树
- 鼠标悬浮(一段时间)才处理
- HDU 6171 Admiral (DFS + 剪枝)
- 正则校验汇总(js)
- Beginning Spring学习笔记——第3章(二)表单处理
- 教你解决Eclipse中SVN比较乱码问题
- 使用eclipes中遇到的问题
- (七)共享模块和依赖注入
- windows 下常用的命令
- 3D麻将游戏开发通用算法
- 新人打卡