bzoj1054 [HAOI2008]移动玩具
【bzoj1054】[HAOI2008]移动玩具
Description
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态。
Input
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
Output
一个整数,所需要的最少移动次数。
Sample Input
1111
0000
1110
0010
0000
1110
0010
1010
0101
1010
0101
Sample Output
4
这是一道bfs的题目,hash去重,然后就好了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 const int NN=(1<<17)+7; 7 const int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0}; 8 9 int bg,ed,h; 10 bool ans[5][5],mark[NN]; 11 struct Node 12 { 13 bool a[5][5]; 14 int step; 15 }q[NN]; 16 17 int hash(bool a[5][5]) 18 { 19 int k=1,s=0; 20 for(int i=1;i<=4;i++) 21 for(int j=1;j<=4;j++) 22 {s+=k*a[i][j];k<<=1;} 23 return s;//hash记录 24 } 25 void bfs() 26 { 27 int t=0,w=1; 28 char ch[5]; 29 for(int i=1;i<=4;i++) 30 { 31 scanf("%s",ch); 32 for(int j=1;j<=4;j++) 33 q[0].a[i][j]=ch[j-1]-'0'; 34 } 35 for(int i=1;i<=4;i++) 36 { 37 scanf("%s",ch); 38 for(int j=1;j<=4;j++) 39 ans[i][j]=ch[j-1]-'0'; 40 } 41 bg=hash(q[t].a); 42 ed=hash(ans); 43 if(bg==ed){printf("0");return;}//特殊考虑 44 45 mark[bg]=1; 46 int x,y; 47 while(t<w) 48 { 49 for(int i=1;i<=4;i++) 50 for(int j=1;j<=4;j++) 51 if(q[t].a[i][j]) 52 for(int k=0;k<4;k++) 53 { 54 x=i+xx[k],y=j+yy[k]; 55 if(q[t].a[x][y]||x>4||y>4||x<1||y<1)continue; 56 swap(q[t].a[i][j],q[t].a[x][y]); 57 h=hash(q[t].a); 58 if(!mark[h]){ 59 if(h==ed){printf("%d",q[t].step+1);return;} 60 mark[h]=1; 61 memcpy(q[w].a,q[t].a,sizeof(q[w].a)); 62 q[w].step=q[t].step+1; 63 w++; 64 } 65 swap(q[t].a[i][j],q[t].a[x][y]); 66 } 67 t++; 68 }//简单宽搜,时间复杂度一千万。 69 } 70 int main() 71 { 72 bfs(); 73 }