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<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 10
 14 #define maxm 10000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define for0(i,n) for(int i=0;i<=(n);i++)
 18 #define for1(i,n) for(int i=1;i<=(n);i++)
 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 22 using namespace std;
 23 int read(){
 24     int x=0,f=1;char ch=getchar();
 25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 27     return x*f;
 28 }
 29 int a[maxn][maxn],b[maxn][maxn],now[maxn][maxn],s[2][140000],flag,ans,h[2],t[2],q[2][140000];
 30 bool book[2][140000];
 31 void init(int t[maxn][maxn]){
 32     for1(i,4)
 33         for1(j,4){
 34             char ch=getchar();
 35             while(ch<'0'||ch>'9')ch=getchar();
 36             t[i][j]=ch-'0';
 37         }
 38 }
 39 int hash(int t[maxn][maxn]){
 40     int tmp=0;
 41     for1(i,4)
 42         for1(j,4){
 43             tmp<<=1;
 44             tmp=tmp|t[i][j];
 45         }
 46     return tmp;
 47 }
 48 void work(int k,int r[maxn][maxn],int w){
 49     int tmp=hash(r);
 50     if(book[k][tmp]==0){
 51         book[k][tmp]++;
 52         s[k][tmp]=w+1;
 53         q[k][++t[k]]=tmp;
 54     }
 55     if(book[k^1][tmp]){
 56         flag=1;ans=s[k^1][tmp]+s[k][tmp];
 57         return;
 58     }
 59 }
 60 void bfs(int k){
 61     memset(now,0,sizeof(now));
 62     int x=q[k][++h[k]],w=s[k][x];
 63     for(int i=4;i>0;i--)
 64         for(int j=4;j>0;j--){
 65             now[i][j]=x&1;
 66             x>>=1;
 67         }
 68     for1(i,4)
 69         for1(j,4){
 70             if(i!=1&&now[i-1][j]!=now[i][j]){
 71                 now[i][j]^=1;now[i-1][j]^=1;
 72                 work(k,now,w);if(flag)return;
 73                 now[i][j]^=1;now[i-1][j]^=1;
 74             }
 75             if(i!=4&&now[i+1][j]!=now[i][j]){
 76                 now[i][j]^=1;now[i+1][j]^=1;
 77                 work(k,now,w);if(flag)return;
 78                 now[i][j]^=1;now[i+1][j]^=1;
 79             }
 80             if(j!=1&&now[i][j-1]!=now[i][j]){
 81                 now[i][j]^=1;now[i][j-1]^=1;
 82                 work(k,now,w);if(flag)return;
 83                 now[i][j]^=1;now[i][j-1]^=1;
 84             }
 85             if(j!=4&&now[i][j+1]!=now[i][j]){
 86                 now[i][j]^=1;now[i][j+1]^=1;
 87                 work(k,now,w);if(flag)return;
 88                 now[i][j]^=1;now[i][j+1]^=1;
 89             }
 90         }
 91 }
 92 int main(){
 93     //freopen("input.txt","r",stdin);
 94     //freopen("output1.txt","w",stdout);
 95     init(a);init(b);
 96     work(0,a,-1);work(1,b,-1);
 97     h[0]=h[1]=0;
 98     while(h[0]<t[0]||h[1]<t[1]){
 99         if(h[1]==t[1])bfs(0);
100         if(flag)break;
101         if(h[0]==t[0])bfs(1);
102         if(flag)break;
103         if(t[1]-h[1]<t[0]-h[0])bfs(1);else bfs(0);
104         if(flag)break;
105     }
106     printf("%d",ans);
107     return 0;
108 }
View Code

 

posted @ 2016-05-23 10:42  HTWX  阅读(106)  评论(0编辑  收藏  举报