这是一道搜索题,我采用双向广搜+状压解决,对每一个状态枚举可以移动的位置,将状态扩展,然后通过对数组状压的方法进行记录结果。
另外,注意对答案为0的特判,因为起始状态与目标状态相同时无法搜出结果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 struct node { 8 int a[5][5]; 9 }; 10 queue<node> q1; 11 queue<node> q2; 12 int vis[1<<17]; 13 int dis[1<<17]; 14 const int fx[5]={0,0,0,1,-1}; 15 const int fy[5]={0,1,-1,0,0}; 16 inline int get(node k) { 17 int num=0,ret=0; 18 for(int i=1;i<=4;i++) { 19 for(int j=1;j<=4;j++) { 20 ret+=k.a[i][j]<<num++; 21 } 22 } 23 return ret; 24 } 25 int bfs() { 26 while(!q1.empty()&&!q2.empty()) { 27 if(q1.size()<=q2.size()) { 28 node now=q1.front(); 29 q1.pop(); 30 for(int i=1;i<=4;i++) 31 for(int j=1;j<=4;j++) 32 if(now.a[i][j]) { 33 for(int k=1;k<=4;k++) { 34 int xx=i+fx[k]; 35 int yy=j+fy[k]; 36 if(xx<1||xx>4||yy<1||yy>4) continue ; 37 if(!now.a[xx][yy]) { 38 swap(now.a[i][j],now.a[xx][yy]); 39 node neww; 40 memcpy(neww.a,now.a,sizeof(now.a)); 41 swap(now.a[i][j],now.a[xx][yy]); 42 int sum=get(neww); 43 if(vis[get(now)]+vis[sum]==3) return dis[get(now)]+dis[sum]; 44 if(vis[sum]==1) continue ; 45 q1.push(neww); 46 vis[sum]=1; 47 dis[sum]=dis[get(now)]+1; 48 } 49 } 50 } 51 } 52 else { 53 node now=q2.front(); 54 q2.pop(); 55 for(int i=1;i<=4;i++) 56 for(int j=1;j<=4;j++) 57 if(now.a[i][j]) { 58 for(int k=1;k<=4;k++) { 59 int xx=i+fx[k]; 60 int yy=j+fy[k]; 61 if(xx<1||xx>4||yy<1||yy>4) continue ; 62 if(!now.a[xx][yy]) { 63 swap(now.a[i][j],now.a[xx][yy]); 64 node neww; 65 memcpy(neww.a,now.a,sizeof(now.a)); 66 swap(now.a[i][j],now.a[xx][yy]); 67 int sum=get(neww); 68 if(vis[get(now)]+vis[sum]==3) return dis[get(now)]+dis[sum]; 69 if(vis[sum]==2) continue ; 70 q2.push(neww); 71 vis[sum]=2; 72 dis[sum]=dis[get(now)]+1; 73 } 74 } 75 } 76 } 77 } 78 return -999999; 79 } 80 int main() { 81 node s,e; 82 for(int i=1;i<=4;i++) { 83 for(int j=1;j<=4;j++) 84 scanf("%1d",&s.a[i][j]); 85 } 86 for(int i=1;i<=4;i++) { 87 for(int j=1;j<=4;j++) 88 scanf("%1d",&e.a[i][j]); 89 } 90 q1.push(s); 91 q2.push(e); 92 vis[get(s)]=1; 93 vis[get(e)]=2; 94 dis[get(s)]=0; 95 dis[get(e)]=0; 96 if(get(s)==get(e)) puts("0"); 97 else printf("%d ",bfs()+1); 98 return 0; 99 }