1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12 13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x r-> d-> r->
2 3 4 1 5 x 7 6 8
ullddrurdllurdruldr
第一次接触A* 写得太想吐了。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include<map> #include<string> #define inf 1<<30 #define eps 1e-7 #define LD long double #define LL long long #define maxn 1000000005 using namespace std; const int ed=322560; int Hash[9]= {1,1,2,6,24,120,720,5040,40320}; struct node { int Map[3][3]; int h,g; int x,y; int Hash; bool operator<(const node n1)const //优先队列第一关键字为h,第二关键字为g { return h!=n1.h?h>n1.h:g>n1.g; } bool cheak() { if(x>=0&&x<3&&y>=0&&y<3) return true ; return false ; } } u,v; int vis[400000]; int pri[400000]; int dir[4][2]= {0,1,0,-1,1,0,-1,0}; bool ok(node tmp) //判断状态是否合法 逆序数为偶数 { int a[9],k=0; for(int i=0; i<3; i++) for(int j=0; j<3; j++) a[k++]=tmp.Map[i][j]; int ans=0; for(int i=0; i<k; i++) for(int j=i+1; j<k; j++) if(a[i]&&a[j]&&a[i]>a[j]) ans++; return (ans&1); } int get_hash(node tmp) //获得康拓值 { int ans=0; int a[9],k=0; for(int i=0; i<3; i++) for(int j=0; j<3; j++) a[k++]=tmp.Map[i][j]; for(int i=0; i<k; i++) { int sum=0; for(int j=0; j<i; j++) if(a[j]>a[i]) sum++; ans+=Hash[i]*sum; } return ans; } int get_h(node tmp) //估价函数 每一个点移动到原来地方的最短路程和 曼哈顿距离 { int ans; for(int i=0; i<3; i++) for(int j=0; j<3; j++) if(tmp.Map[i][j]) ans+=abs(i-(tmp.Map[i][j]-1)/3)+abs(j-(tmp.Map[i][j]-1)%3); return ans; } void print() { string str; str.clear(); int st=ed; while(pri[st]!=-1) { if(vis[st]==0) { str+='r'; } else if(vis[st]==1) { str+='l'; } else if(vis[st]==2) { str+='d'; } else str+='u'; st=pri[st]; } for(int i=str.size()-1;i>=0;i--) cout<<str[i]; cout<<endl; return ; } void bfs() { priority_queue<node >q; q.push(u); memset(vis,-1,sizeof(vis)); memset(pri,-1,sizeof(pri)); vis[u.Hash]=-2; while(!q.empty()) { //cout<<q.size()<<endl; u=q.top(); q.pop(); for(int i=0; i<4; i++) { v=u; v.x+=dir[i][0]; v.y+=dir[i][1]; if(v.cheak()) { swap(v.Map[v.x][v.y],v.Map[u.x][u.y]); v.Hash=get_hash(v); if(vis[v.Hash]==-1&&!ok(v)) { v.h=get_h(v); v.g++; vis[v.Hash]=i; pri[v.Hash]=u.Hash; q.push(v); } } if(v.Hash==ed) { print(); return ; } } } } int main() { char ch[100]; memset(ch,0,sizeof(ch)); while(cin>>ch[0]) { for(int i=1; i<9; i++) cin>>ch[i]; for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { if(ch[i*3+j]=='x') { u.Map[i][j]=0; u.x=i; u.y=j; u.Hash=get_hash(u); u.h=get_h(u); u.g=0; } else u.Map[i][j]=ch[i*3+j]-'0'; } } if(u.Hash==ed) { cout<<endl; continue ; } if(!ok(u)) bfs(); else cout<<"unsolvable"<<endl; } }