[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

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 }

 

posted @ 2017-12-18 14:21  J_william  阅读(421)  评论(0编辑  收藏  举报