1054: [HAOI2008]移动玩具
Submit: 2844 Solved: 1594
[Submit][Status][Discuss]
Description
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动
时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移
动到某人心中的目标状态。
Input
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空
行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
Output
一个整数,所需要的最少移动次数。
Sample Input
1111
0000
1110
0010
1010
0101
1010
0101
0000
1110
0010
1010
0101
1010
0101
Sample Output
4
状压DP+记忆化
将4*4矩阵压缩成16位数,并用记忆化搜索剪枝
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 7 const int mv[4]={4,-4,1,-1}; 8 char ch[10]; 9 int s,t,q,now; 10 int dist[1<<16]; 11 queue<int> Q; 12 13 void move(int i) 14 { 15 if(now&(1<<i)) return; 16 int x=now+(1<<i); 17 if(dist[x]) return; 18 dist[x]=dist[q]+1; 19 Q.push(x); 20 } 21 22 int main() 23 { 24 for(int i=0;i<4;i++) 25 { 26 scanf("%s",ch); 27 for(int j=0;j<4;j++) 28 s=s*2+ch[j]-'0'; 29 } 30 for(int i=0;i<4;i++) 31 { 32 scanf("%s",ch); 33 for(int j=0;j<4;j++) 34 t=t*2+ch[j]-'0'; 35 } 36 Q.push(s);dist[s]=1; 37 while(!Q.empty()) 38 { 39 q=Q.front();Q.pop(); 40 if(q==t) 41 { 42 printf("%d",dist[t]-1); 43 break; 44 } 45 for(int i=0;i<16;i++) 46 if((1<<i)&q) 47 { 48 now=(1<<i)^q; 49 if(i/4<3) move(i+4); 50 if(i/4>0) move(i-4); 51 if(i%4<3) move(i+1); 52 if(i%4>0) move(i-1); 53 } 54 } 55 return 0; 56 }