A*模板
可以发现无论怎么动x逆序对奇偶性不变,可用这个性质判unsolve
状态判重可用康托展开
估价函数h(n)的求法为计算图上每一个点到目标的曼哈顿距离之和
1 #include<cmath> 2 #include<queue> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 int n,m,cnt,tot,stp; 8 int dx[4]={0,1,0,-1}; 9 int dy[4]={1,0,-1,0}; 10 int val[10]={0,1,1,2,6,24,120,720,5040,40320}; 11 char sc[12][3]; 12 char ans[500005]; 13 bool vis[500005]; 14 struct node{ 15 int posx; 16 int sta[4][4]; 17 int hs,hn,gn,fn; 18 }fr,ed; 19 struct PRE{ 20 char w; 21 int p; 22 }pre[500005]; 23 bool check(node x){ 24 int tmp[10];int tp=0;int ret=0; 25 for(int i=1;i<=3;i++){ 26 for(int j=1;j<=3;j++){ 27 tmp[++tp]=x.sta[i][j]; 28 } 29 } 30 for(int i=1;i<=9;i++){ 31 if(!tmp[i])continue; 32 for(int j=i+1;j<=9;j++){ 33 if(!tmp[j])continue; 34 if(tmp[j]<tmp[i])ret++; 35 } 36 } 37 return (ret&1); 38 } 39 int gethash(node x){ 40 int tmp[10];int tp=0;int ret=0,c=0; 41 for(int i=1;i<=3;i++){ 42 for(int j=1;j<=3;j++){ 43 tmp[++tp]=x.sta[i][j]; 44 } 45 } 46 for(int i=1;i<=9;c=0,i++){ 47 for(int j=1;j<i;j++){ 48 if(tmp[j]<tmp[i])c++; 49 } 50 ret+=c*val[i]; 51 } 52 return ret; 53 } 54 int gethn(node x){ 55 int ret=0; 56 for(int i=1;i<=3;i++){ 57 for(int j=1;j<=3;j++){ 58 if(x.sta[i][j])ret+=abs(i-((x.sta[i][j]-1)/3+1))+abs(j-((x.sta[i][j]-1)%3+1)); 59 } 60 } 61 return ret; 62 } 63 bool operator<(node a,node b){ 64 return a.fn>b.fn; 65 } 66 void astar(){ 67 priority_queue<node>que; 68 que.push(fr); 69 for(int i=0;i<=500000;i++){ 70 pre[i].p=-1; 71 } 72 memset(vis,false,sizeof(vis)); 73 vis[fr.hs]=true; 74 while(!que.empty()){ 75 node u=que.top(); 76 que.pop(); 77 int x=(u.posx-1)/3+1; 78 int y=(u.posx-1)%3+1; 79 for(int i=0;i<4;i++){ 80 node v=u; 81 int xx=x+dx[i]; 82 int yy=y+dy[i]; 83 if(xx<1||xx>3||yy<1||yy>3)continue; 84 swap(v.sta[x][y],v.sta[xx][yy]); 85 v.posx=(xx-1)*3+yy; 86 v.hs=gethash(v); 87 if(!vis[v.hs]){ 88 v.gn=u.gn+1; 89 v.hn=gethn(v); 90 v.fn=v.hn+v.gn; 91 pre[v.hs].p=u.hs; 92 if(i==0)pre[v.hs].w='r'; 93 if(i==1)pre[v.hs].w='d'; 94 if(i==2)pre[v.hs].w='l'; 95 if(i==3)pre[v.hs].w='u'; 96 vis[v.hs]=true; 97 if(v.hs==stp){ 98 return; 99 } 100 que.push(v); 101 } 102 } 103 } 104 } 105 void print(){ 106 int now=stp;tot=0; 107 while(pre[now].p!=-1){ 108 ans[++tot]=pre[now].w; 109 now=pre[now].p; 110 } 111 for(int i=tot;i>=1;i--){ 112 printf("%c",ans[i]); 113 } 114 printf(" "); 115 } 116 int main(){ 117 while(scanf("%s",sc[1]+1)>0){ 118 cnt=0; 119 for(int i=2;i<=9;i++)scanf("%s",sc[i]+1); 120 for(int i=1;i<=3;i++){ 121 for(int j=1;j<=3;j++){ 122 fr.sta[i][j]=sc[++cnt][1]-'0'; 123 if(fr.sta[i][j]>8||fr.sta[i][j]<1){ 124 fr.posx=(i-1)*3+j; 125 fr.sta[i][j]=0; 126 } 127 ed.sta[i][j]=(i-1)*3+j; 128 ed.sta[3][3]=0; 129 } 130 } 131 stp=gethash(ed); 132 fr.fn=fr.hn=gethn(fr); 133 fr.hs=gethash(fr); 134 if(stp==fr.hs){ 135 printf(" "); 136 continue; 137 } 138 if(check(fr)){ 139 printf("unsolvable "); 140 continue; 141 } 142 astar();print(); 143 } 144 return 0; 145 }