为什么就是跑不出0ms
八数码0.0,我又来水博客了。
IDA*算法,A*为曼哈顿距离,判重用康拓展开。
#include<cstring> #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> using namespace std; int a[4][4]; int dx[]={0,0,-1,1}; int dy[]={-1,1,0,0}; char s[]="123804765"; int end[4][4]; int x,y; int dep; bool vis[400000]; int ca[]={1,1,2,6,24,120,720,5040,40320,362880}; inline int cantor() { int sum=0; for(int i=0;i<9;i++) { int num=0; for(int j=i+1;j<9;j++) if(a[i/3][i%3]<a[j/3][j%3]) num++; sum+=(num*ca[9-i-1]); } return sum+1; } struct node { int x,y; }p[12]; inline bool ok() //判断是否结束 { for(int i=0;i<3;i++) { for(int j=0;j<3;j++) { if(p[a[i][j]].x!=i||p[a[i][j]].y!=j) return false; } } return true; } inline int dist(int x1,int y1,int x2,int y2)//求两点的曼哈顿距离 { return abs(x1-x2)+abs(y1-y2); } int h() //求估价值 { int l=0; for(int i=0;i<3;i++) { for(int j=0;j<3;j++) { if(a[i][j]==0) continue; l+=dist(i,j,p[a[i][j]].x,p[a[i][j]].y); } } return l; } bool dfs(int now,int x,int y) //(x,y)保存0的位置 { if(ok()) return true; if(now+h()>dep) return false; for(int d=0;d<4;d++) { int nx=x+dx[d]; int ny=y+dy[d]; if(nx>=0&&nx<3&&ny>=0&&ny<3) { int can=cantor(); if(vis[can]) continue; vis[can]=true; swap(a[nx][ny],a[x][y]); if(dfs(now+1,nx,ny)) return true; swap(a[nx][ny],a[x][y]); vis[can]=false; } } return false; } char str[12]; int main() { scanf("%s",str); for(int i=0,b=0;i<3;i++) { for(int j=0;j<3;b++,j++) { p[s[b]-'0'].x=i; //记录目标数字对应的位置 p[s[b]-'0'].y=j; a[i][j]=str[b]-'0'; if(!a[i][j]) { x=i; y=j; } } } cantor(); for(dep=h();;dep++) //迭代加深搜索 { if(dfs(0,x,y)) break; } printf("%d\n",dep); return 0; }