BZOJ1054: [HAOI2008]移动玩具(bfs+hash)

题意:传送门

题解:直接bfs,最重要的是设计出如何进行判重,然后可以将棋盘看成一个16进制数就可以了。

附上代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=65536;
int bg,ed,h,xx[]={0,0,1,-1},yy[]={1,-1,0,0};
bool ans[5][5],mark[maxn];
struct data{bool a[5][5];int step;}q[maxn];
int HASH(bool a[5][5])
{
    int k=1,s=0;
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            s+=k*a[i][j];k<<=1;
        }
    }
    return s;
}
void bfs()
{
    int s=0,t=1;
    char ch[5];
    for(int i=1;i<=4;i++){
        scanf("%s",ch);
        for(int j=1;j<=4;j++){
            q[0].a[i][j]=ch[j-1]-48;
        }
    }
    q[0].step=0;
    for(int i=1;i<=4;i++){
        scanf("%s",ch);
        for(int j=1;j<=4;j++){
            ans[i][j]=ch[j-1]-48;
        }
    }
    bg=HASH(q[s].a);ed=HASH(ans);
    if(bg==ed){printf("%d\n",0);return ;}
    mark[bg]=1;
    while(s<t){
        for(int i=1;i<=4;i++){
            for(int j=1;j<=4;j++){
                if(q[s].a[i][j]){
                    for(int k=0;k<4;k++){
                        int x=i+xx[k],y=j+yy[k];
                        if(q[s].a[x][y]||x<1||x>4||y<1||y>4)continue;
                        swap(q[s].a[i][j],q[s].a[x][y]);
                        h=HASH(q[s].a);
                        if(h==ed){printf("%d\n",q[s].step+1);return;}
                        if(mark[h]){swap(q[s].a[i][j],q[s].a[x][y]);continue;}
                        mark[h]=1;
                        memcpy(q[t].a,q[s].a,sizeof(q[s].a));
                        q[t++].step=q[s].step+1;
                        swap(q[s].a[i][j],q[s].a[x][y]);
                    }
                }
            }
        }
        s++;
    }
}
int main()
{
    bfs();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值