[bzoj1054]移动玩具

裸BFS。。哈希表判一下重就行。。(注意要解压状态!)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <map>
 7 #include <string>
 8 #include <vector>
 9 #include <stack>
10 #include <cmath>
11 #include <queue>
12 using namespace std;
13 
14 char st[10][10],ed[10][10];
15 int h1,h2;
16 bool v[1<<20];
17 int hasher(char st_[10][10]=st){
18     int ret=0;
19     for(int i=0;i<4;i++)
20         for(int j=0;j<4;j++)
21             ret=(ret<<1)|st_[i][j]-'0';
22     return ret;
23 }
24 int mv[10][2]={
25     {0,1},
26     {1,0},
27     {-1,0},
28     {0,-1}
29 };
30 queue<pair<int,int> >q;
31 int main(){
32     for(int i=0;i<4;i++)scanf("%s",st[i]);
33     for(int i=0;i<4;i++)scanf("%s",ed[i]);
34     h1=hasher();
35     h2=hasher(ed);
36     v[h1]=1;
37     q.push(make_pair(h1,0));
38     while(q.size()){
39         pair<int,int> top=q.front();q.pop();
40         if(top.first==h2){printf("%d\n",top.second);return 0;}
41         for(int i=3;i>=0;i--){
42             for(int j=3;j>=0;j--){
43                 st[i][j]=(top.first&1)+'0';
44                 top.first>>=1;
45             }
46         }
47         for(int i=0;i<4;i++){
48             for(int j=0;j<4;j++){
49                 if(st[i][j]=='1'){
50                     for(int k=0;k<4;k++){
51                         int x=i+mv[k][0],y=j+mv[k][1];
52                         if(0<=x&&x<4&&0<=y&&y<4&&st[x][y]=='0'){
53                             swap(st[i][j],st[x][y]);
54                             h1=hasher();
55                             if(!v[h1]){
56                                 q.push(make_pair(h1,top.second+1));
57                                 v[h1]=1;
58                             }
59                             swap(st[i][j],st[x][y]);
60                         }
61                     }
62                 }
63             }
64         }
65     }
66 }
View Code

 

转载于:https://www.cnblogs.com/KingSann/articles/6240927.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值