hdu 1043 八数码问题-A*搜索
来源:互联网 发布:网络教育本科第二学位 编辑:程序博客网 时间:2024/06/05 13:27
http://acm.hdu.edu.cn/showproblem.php?pid=1043
题意。。不再赘述,和小时候玩的玩具很像。
思路:今天人生终于完整了。。。
来一个普通的A*搜索的思路。。。(感觉会不会倒着打表更快?)
所谓A*搜索个人理解就是对于BFS的一个优先级队列优化。。。至于用什么作为关键字就是一个F(F=H+G)
H是估价函数,表示距离答案还有大约多少,越近H越高。。G是已花代价。。当然对于这个题目G并没有什么用,因为我们并不求最优,所以不如直接去直接以H作为关键字。
对于本题,和最终答案越一样那么就越应该先搜索,所以将9个数字的和本来应该在的位置的曼哈顿距离加起来就可以判断是不是更接近目标了。。
所以我们就可以设计一个看起来还不错的H函数。。。
有了估价函数就很愉快的A*啦
代码:
#include <bits/stdc++.h>using namespace std;const int dis[12] = {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};int tmp[10];char s[10];const int maxn=1e5*4;int arr[10];int vis[maxn];int last[maxn+10];int how[maxn+10];int ans=-1;int Cantor(int x, int len){ int c=0; while(x){ tmp[c++]=x%10; x/=10; } int resl = 1; for(int i = 0; i < len; i++){ int counts = 0; for(int k = i + 1; k < len; k++){ if(tmp[i] > tmp[k]){ counts++; } } resl = resl + dis[len-i-1] * counts; } return resl;}int tran(int x,int h){ int c=0,ret=0,idx=0;; while(x){ tmp[c++]=x%10; if(tmp[c-1]==9) idx=c-1; x/=10; } if(h==0){ if(idx<3) return -1; else swap(tmp[idx],tmp[idx-3]); } else if(h==1){ if(idx%3==2) return -1; else swap(tmp[idx],tmp[idx+1]); } else if(h==2){ if(idx>5) return -1; else swap(tmp[idx],tmp[idx+3]); } else if(h==3){ if(idx%3==0) return -1; else swap(tmp[idx],tmp[idx-1]); } for(int i=0,j=1;i<9;i++,j*=10) ret+=tmp[i]*j; return ret;}int val(int x){ int c=0,ret=0; while(x){ tmp[c++]=x%10; ret+=abs((c-1)%3-(tmp[c-1]-1)%3)+abs((c-1)/3-(tmp[c-1]-1)/3); x/=10; } return -ret;}struct node{ int val,num,id; node(){}; node(int a,int b,int c):val(a),num(b),id(c){};};bool operator <(const node &a,const node &b){ return a.val<b.val;}bool Astar(){ memset(vis,0,sizeof(vis)); memset(last,-1,sizeof(last)); priority_queue<node> P; int x=0,cnt=0; for(int i=0,j=1;i<9;i++,j*=10) x+=arr[i]*j; P.push(node(0,x,cnt++)); vis[Cantor(x,9)]=1; while(!P.empty()){ node t=P.top(); P.pop(); ans=t.id; if(t.num==987654321) return true; if(cnt>2000) return false; for(int i=0;i<4;i++){ int x=tran(t.num,i); if(x!=-1&&vis[Cantor(x,9)]==0){ vis[Cantor(x,9)]=1; last[cnt]=t.id; how[cnt]=i; P.push(node(val(x),x,cnt++)); } } } return false;}char re[maxn];void pr(int x){ int c=0; while(x!=0){ if(how[x]==0) re[c++]='u'; else if(how[x]==1) re[c++]='r'; else if(how[x]==2) re[c++]='d'; else if(how[x]==3) re[c++]='l'; x=last[x]; } for(int i=c-1;i>=0;i--) printf("%c",re[i]); puts("");}int main(){ while(cin>>s[0]>>s[1]>>s[2]>>s[3]>>s[4]>>s[5]>>s[6]>>s[7]>>s[8]){ for(int i=0;i<9;i++){ if(s[i]=='x') arr[i]=9; else arr[i]=(int)(s[i]-'0'); } if(Astar()){ //cout<<"ANS"<<ans<<endl; pr(ans); } else{ puts("unsolvable"); } } return 0;}
0 0
- HDU 1043 八数码问题 A*搜索
- HDU 1043 八数码问题 A*搜索
- hdu 1043 八数码问题-A*搜索
- hdu 1043 Eight(八数码问题 高级搜索: A* 搜索)
- HDU 1043 Eight 八数码问题 A*搜索 启发式算法
- HDU 1043 八数码(A*搜索)
- A*搜索 - 八数码问题
- HDU 1043 八数码问题 A*搜索+康拓展开+逆序对判断+路径输出
- hdu 1043 八数码 A*
- 八数码问题——A*搜索
- Poj1077/HDU1043(A*搜索)八数码问题
- 八数码问题-启发式搜索(A*算法)
- hdu 1043 八数码 经典搜索问题 BFS+MAP
- 八数码A*搜索
- hdu 1043(八数码问题)
- HDU:1043 八数码问题
- hdu 1043 eight 八数码问题 bfs 和 A*
- hdu 1043 A*算法解决八数码问题
- 开发的准备工作
- codeforces round#377 div2 D
- android6.0系统 PowerManager深入分析(非常详细)
- Servlet 文件上传
- ida 插件编写
- hdu 1043 八数码问题-A*搜索
- 28-PAE分页下的PDT-PTT基址
- 标准的Struts-2.3.31开发环境搭建
- 使用Ajax.dll前台调用后台方法
- Unity整理内容方便初学者查看(第二篇_输入Input)
- 基本的全选,反选,全不选.批删,批量添加.即点即改
- EditPlus 自动格式化js、html、css
- c# 读写excel要添加哪些引用
- 大端和小端的区别