这算是一道双向广搜或者是A*题,我用的是双向广搜,从初始状态和目标状态分别扩展状态,当他们第一次相遇时所用的步数即为答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 int ans=123804765; 4 int n; 5 const int fx[4]={0,0,1,-1}; 6 const int fy[4]={1,-1,0,0}; 7 queue<int> q; 8 map<int,int> vis; 9 map<int,int> dis; 10 int a[5][5]; 11 int main() 12 { 13 scanf("%d",&n); 14 if(n==ans) 15 { 16 puts("0"); 17 return 0; 18 } 19 q.push(n); 20 q.push(ans); 21 vis[n]=1; 22 vis[ans]=2; 23 dis[n]=0; 24 dis[ans]=1; 25 int x,y; 26 while(!q.empty()) 27 { 28 int now=q.front(); 29 q.pop(); 30 int neww=now; 31 for(int i=3;i>=1;i--) 32 for(int j=3;j>=1;j--) 33 { 34 a[i][j]=neww%10; 35 neww/=10; 36 if(a[i][j]==0) x=i,y=j; 37 } 38 for(int k=0;k<4;k++) 39 { 40 int xx=x+fx[k]; 41 int yy=y+fy[k]; 42 if(xx<1||xx>3||yy<1||yy>3) continue ; 43 swap(a[x][y],a[xx][yy]); 44 neww=0; 45 for(int i=1;i<=3;i++) 46 for(int j=1;j<=3;j++) 47 neww=neww*10+a[i][j]; 48 if(vis[neww]==vis[now]) 49 { 50 swap(a[x][y],a[xx][yy]); 51 continue ; 52 } 53 if(vis[neww]+vis[now]==3) 54 { 55 printf("%d ",dis[neww]+dis[now]); 56 return 0; 57 } 58 dis[neww]=dis[now]+1; 59 vis[neww]=vis[now]; 60 q.push(neww); 61 swap(a[x][y],a[xx][yy]); 62 } 63 } 64 return 0; 65 }