【BZOJ 1054】 [HAOI2008]移动玩具

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
 
这个题貌似在哪见过,然后找不到了
其实也不需要见过,双向BFS就够了,就是我的搜索代码太丑
 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 int map[4][4],mb[4][4],b[4][4],bs[2][140000],q[2][140000],h[2],t[2],ans;
 5 bool pd[2][140000],flag;
 6 int hash(int b[4][4]){
 7     int mid=0;
 8     for (int i=0;i<4;i++)
 9         for (int j=0;j<4;j++){
10             mid=mid<<1;
11             mid=mid|b[i][j];
12         }
13     return mid;
14 }
15  
16 void make(int v,int b[4][4],int f){
17     int mid=hash(b);
18     if (!pd[v][mid]) {
19         pd[v][mid]++;
20         bs[v][mid]=f+1;
21         q[v][++t[v]]=mid;
22     }
23     if(pd[v^1][mid]) {
24         flag=1;ans=bs[v][mid]+bs[v^1][mid];//这个地方不需要-1
25         return;
26     }
27 }
28  
29 void bfs(int v){
30     memset(b,0,sizeof(b));
31     int now=q[v][++h[v]],w=bs[v][now];
32     int x=3,y=3;
33     for (int i=1;i<=16;i++){
34         b[x][y]=now&1;
35         now=now>>1;
36         y--; if(y==-1)y=3,x--;
37     }
38     for (int i=0;i<=3;i++)
39         for (int j=0;j<4;j++){
40             if (i!=0&&b[i-1][j]!=b[i][j]) {
41                 b[i][j]^=1;b[i-1][j]^=1;
42                 make(v,b,w);
43                 if (flag) return;
44                 b[i][j]^=1;b[i-1][j]^=1;
45             }
46             if (i!=3&&b[i+1][j]!=b[i][j]){
47                 b[i][j]^=1;b[i+1][j]^=1;
48                 make(v,b,w);
49                 if (flag) return;
50                 b[i][j]^=1;b[i+1][j]^=1;
51             }
52             if (j!=0&&b[i][j]!=b[i][j-1]){
53                 b[i][j]^=1;b[i][j-1]^=1;
54                 make(v,b,w);
55                 if (flag) return;
56                 b[i][j]^=1;b[i][j-1]^=1;
57             }
58             if (j!=3&&b[i][j]!=b[i][j+1]){
59                 b[i][j]^=1;b[i][j+1]^=1;
60                 make(v,b,w);
61                 if (flag) return;
62                 b[i][j]^=1;b[i][j+1]^=1;
63             }
64         }
65 }
66  
67 int main(){
68     char s[20];
69     for (int i=0;i<4;i++){
70         scanf("%s",s);
71         for (int j=0;j<4;j++)
72         map[i][j]=s[j]-'0';
73     }
74     for (int i=0;i<4;i++){
75         scanf("%s",s);
76         for (int j=0;j<4;j++)
77         mb[i][j]=s[j]-'0';
78     }
79     h[0]=h[1]=0;
80     make(0,map,-1);make(1,mb,-1);
81     while(h[0]<t[0]||h[1]<t[1]){
82         if (h[1]==t[1]) bfs(0);
83         if (flag) break;
84         if (h[0]==t[0]) bfs(1);
85         if (flag) break;
86         if (t[1]-h[1]<t[0]-h[0]) bfs(1);else bfs(0);
87         if (flag) break;
88     }
89     printf("%d",ans);
90 }
原文地址:https://www.cnblogs.com/wuminyan/p/5191631.html