Admiral HDU
来源:互联网 发布:成都地铁 知乎 编辑:程序博客网 时间:2024/04/30 21:29
这题很像那道八数码的题目,可以把21个位置每个位置有6种数,那么总共有21的6次方种状态,那么是可以用一个longlong来表示状态,用set来判重的。但是这样还是不够快。我们可以利用A星算法来优化搜索过程A星算法的知识,A星算法中有两个重要的值,已走步数和到终点估计值,已走步数这个很容易得到,到终点的估计值这个我们可以估计每个不合法的点直接挪过去他该去的那一行该走的步数。估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。那么这样就有了估价值,跑A星算法的时候就能优先搜索可能是最优解的方法了。
#include<bits/stdc++.h>using namespace std;struct Status{ int i,j; int d,h; long long enco; friend bool operator < (const Status &a,const Status &b) { return a.d+a.h>b.d+b.h; }};int cx[]= {-1,-1,1,1};int cy[]= {-1,0,0,1};int a[6][6];long long encode(int a[6][6]){ long long code = 0; long long base = 1; for(int i=0; i<6; i++) for(int j=0; j<=i; j++) { code+=a[i][j]*base; base*=6; } return code;}void decode(int a[6][6],long long code){ long long base = 6; for(int i=0; i<6; i++) for(int j=0; j<=i; j++) { a[i][j]=code%base; code/=base; }}int Astar(int si,int sj,int h){ set<long long> rec; Status status = {si,sj,0,h}; status.enco=encode(a); rec.insert(status.enco); priority_queue<Status> que; que.push(status); while(que.size()) { Status top = que.top(); que.pop(); for(int i=0; i<4; i++) { int nx = cx[i]+top.i; int ny = cy[i]+top.j; if(nx<0||nx>5||ny<0||ny>5||nx<ny) continue; Status tmp = top; int a[6][6]; decode(a,tmp.enco); tmp.d++; swap(a[nx][ny],a[tmp.i][tmp.j]); int h=0; for(int i=0; i<6; i++) for(int j=0; j<=i; j++) h+=abs(a[i][j]-i); h/=2; tmp.h=h; tmp.i=nx,tmp.j=ny; tmp.enco=encode(a); if(rec.count(tmp.enco)) continue; else rec.insert(tmp.enco); if(tmp.h==0) return tmp.d; if(tmp.d+tmp.h<20) que.push(tmp); } } return -1;}int main(){ if (fopen("in.txt", "r") != NULL) { freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); } int t; cin>>t; while(t--) { int si,sj; int h=0; for(int i=0; i<6; i++) for(int j=0; j<=i; j++) { scanf("%d",&a[i][j]); if(a[i][j]!=i) h+=abs(a[i][j]-i); if(a[i][j]==0) si=i,sj=j; } h/=2; if(h>=20) {puts("too difficult");continue;} if(h==0) {puts("0");continue;} int ans = Astar(si,sj,h); if(ans!=-1) printf("%d\n",ans); else puts("too difficult"); } return 0;}
阅读全文
0 0
- Admiral HDU
- HDU 6171 Admiral
- HDU 6171 Admiral (DFS + 剪枝)
- HDU 6171 Admiral [双向bfs+hash]
- HDU 6171 Admiral(双向宽搜)
- hdu 6171 Admiral 双向bfs+hash
- [hdu 6171 Admiral]Hash+暴搜+中途相遇法
- Hdu 6171 Admiral【双向Bfs+字符串哈希】
- HDU-2017 多校训练赛10-1001-Admiral
- 【多校训练】hdu 6171 Admiral 双向bfs+hash
- UVa1658 Admiral
- Admiral UVA
- Admiral UVA
- HDU 6171 Admiral 双向搜索(meet in the middle) + 哈希
- 2017多校联合第十场/HDU 6171 Admiral 双向bfs + 哈希
- 2017 Multi-University Training Contest 10 1001 Admiral HDU 6171 (双向搜索 哈希)
- LA6266 Admiral 费用流
- UVa 1658 Admiral
- C#基础-009 逻辑运算
- java设计模式六大原则之场景应用分析
- 点击新闻条目跳转viewpager+photoview显示图片
- 【python图像处理】gif动态图的解析与合成
- [003-u-boot-Exynos4412] 移植SPL阶段
- Admiral HDU
- HDU6172-Array Challenge
- DOM--节点操作
- 月报统计:根据数据库表字段并按月查询某列的总和(sum)
- 剑指offer——扑克牌顺子
- (八)Spring Boot整合ActiveMQ
- RT3070wifi+linux(TMS320DM368)移植
- mysql笔记七——Java实现excel表的读写(导出mysql数据库的所有表到excel表)
- 使用BMfont制作含有"中文图片"的.fnt格式字体合图