1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
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

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 }

 

posted @ 2018-08-17 20:22  InWILL  阅读(309)  评论(0编辑  收藏  举报