首页 > 代码库 > bzoj 1054 移动玩具

bzoj 1054 移动玩具

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1054

题解:

  瞎基本搜是没有希望的,还是正常的BFS比较靠谱
  看出4*4的格子每行串在一起即是一个01串,可以用类似于状态压缩的思想解决,将其转化为十进制数,主要为了判断是否已经到了理想的状态

  队列中存储状态,在BFS的时候取出队首,针对每一个棋子的四种移动产生新的状态,再入队处理即可

  (有点搞不懂当时为什么要用“hash”来命名这种状态压缩……)

 1 #include<cstdio>
 2 #include<cstring>
 3 int st,en,_x[]={0,0,0,-1,1},_y[]={0,1,-1,0,0};
 4 bool vis[65536];
 5 struct node
 6 {
 7     bool status[5][5];
 8     int dep;
 9 }q[65536];
10 inline int hash(bool a[5][5])
11 {
12     int k=1,ans=0;
13     for(int i=1;i<=4;i++)
14     {
15         for(int j=1;j<=4;j++)
16         {
17             ans+=a[i][j]*k;
18             k<<=1;
19         }
20     }
21     return ans;
22 }
23 void init()
24 {
25     char temp[5];
26     bool temp2[5][5];
27     for(int i=1;i<=4;i++)
28     {
29         scanf("%s",temp+1);
30         for(int j=1;j<=4;j++)
31         {
32             q[1].status[i][j]=temp[j]-0;
33         }
34     }
35     for(int i=1;i<=4;i++)
36     {
37         scanf("%s",temp+1);
38         for(int j=1;j<=4;j++)
39         {
40             temp2[i][j]=temp[j]-0;
41         }
42     }
43     st=hash(q[1].status);
44     en=hash(temp2);
45 }
46 void bfs()
47 {
48     vis[st]=true;
49     int head=1,tail=2;
50     while(head<tail)
51     {
52         for(int i=1;i<=4;i++)
53         {
54             for(int j=1;j<=4;j++)
55             {
56                 if(q[head].status[i][j])
57                 {
58                     for(int k=1;k<=4;k++)
59                     {
60                         int x=i+_x[k],y=j+_y[k];
61                         if(q[head].status[x][y]||!x||!y||x>4||y>4)continue;
62                         q[head].status[i][j]=false;
63                         q[head].status[x][y]=true;
64                         int hash_of_status=hash(q[head].status);
65                         if(!vis[hash_of_status])
66                         {
67                             if(hash_of_status==en)
68                             {
69                                 printf("%d",q[head].dep+1);
70                                 return;
71                             }
72                             memcpy(q[tail].status,q[head].status,sizeof(q[tail].status));
73                             q[tail++].dep=q[head].dep+1;
74                             vis[hash_of_status]=true;
75                         }
76                         q[head].status[i][j]=true;
77                         q[head].status[x][y]=false;
78                     }
79                 }
80             }
81         }
82         head++;
83     }
84 }
85 int main()
86 {
87     init();
88     if(st==en)
89     {
90         printf("0\n");
91         return 0;
92     }
93     bfs();
94     return 0;
95 }

 

bzoj 1054 移动玩具