[HAOI2008]移动玩具
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2561 Solved: 1430
[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
思路
我们可以算一下,状态数绝对不会超过1<<16,所有放心搜就好了。
代码实现
1 #include<cstdio> 2 #include<cstring> 3 const int size=2e5+10; 4 char ch[6]; 5 int s,t; 6 void in(int&x){ 7 for(int i=0;i<4;i++){ 8 scanf("%s",ch); 9 for(int j=0;j<4;j++) if(ch[j]-'0') x+=1<<(i*4+j); 10 } 11 } 12 int f[4]={-4,+1,+4,-1}; 13 int q[size],head,tail; 14 int d[size]; 15 void bfs(){ 16 q[tail++]=s,d[s]=1; 17 int now,nd,nw; 18 while(head<tail){ 19 now=q[head++],nd=d[now]+1; 20 for(int i=0;i<16;i++) 21 if(now&(1<<i)){ 22 for(int j=0;j<4;j++){ 23 if(j==0&&i/4==0) continue; 24 if(j==1&&i%4==3) continue; 25 if(j==2&&i/4==3) continue; 26 if(j==3&&i%4==0) continue; 27 nw=i+f[j]; 28 if(now&(1<<nw)) continue; 29 nw=now^(1<<i)^(1<<nw); 30 if(nd<d[nw]) d[nw]=nd,q[tail++]=nw; 31 if(nw==t) return; 32 } 33 } 34 } 35 } 36 int main(){ 37 in(s),in(t); 38 memset(d,0x7f,sizeof(d)); 39 bfs(); 40 printf("%d\n",d[t]-1); 41 return 0; 42 }