BZOJ1054 移動玩具 [BFS][HASH]

1054: [HAOI2008]移動玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2407  Solved: 1345
[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

HINT

Source

思考

deque水水,就是一個類似8數碼的問題,爆搜可過。用hash判重即可。

#include<bits/stdc++.h>
using namespace std;
int head,tail,top,xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
bool ans[5][5],mk[100005];
struct data{
    bool a[5][5];
    int step;
}tmp;
deque<data> Q;
int hash(bool a[5][5]){
    register int i,j,k=1,s=0;
    for(i=1;i<=4;i++)
        for(j=1;j<=4;j++)
            s+=k*a[i][j],k<<=1;
    return s;
}
int main(){
    register int i,j,x,y,k;
    char ch[5];
    for(i=1;i<=4;i++){
        scanf("%s",ch);
        for(j=1;j<=4;j++)
            tmp.a[i][j]=ch[j-1]-'0';
    }
    Q.push_front(tmp);
    for(i=1;i<=4;i++){
        scanf("%s",ch);
        for(j=1;j<=4;j++)
            ans[i][j]=ch[j-1]-'0';
    }
    head=hash(Q.front().a);
    tail=hash(ans);
    if(head==tail)return puts("0"),0;
    mk[head]=1;Q.push_back(tmp);
    while(!Q.empty()){
        for(i=1;i<=4;i++)
            for(j=1;j<=4;j++)
                if(Q.front().a[i][j])
                for(k=0;k<4;k++){
                    x=i+xx[k],y=j+yy[k];
                    if(Q.front().a[x][y]||x>4||y>4||x<1||y<1)continue;
                    swap(Q.front().a[i][j],Q.front().a[x][y]);
                    top=hash(Q.front().a);
                    if(!mk[top]){
                        if(top==tail)return printf("%d",Q.front().step+1),0;
                        mk[top]=1;
                        memcpy(Q.back().a,Q.front().a,sizeof(Q.back().a));
                        Q.back().step=Q.front().step+1;
                        Q.push_back(tmp);
                    }
                    swap(Q.front().a[i][j],Q.front().a[x][y]);
                }
        Q.pop_front();
    }
    return 0;
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章