您的位置:首页 > 其它

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

2018-03-05 20:48 281 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1054

震惊!省选竟然出NOIP难度的题!

首先我们观察到4*4的矩阵,状态非常少,那么就在暗示着我们要状压,那么用什么来状压呢?就可以用二进制哈希,用一个数来表示一个4*4 01矩阵的状态。

暴力宽搜即可,记得回溯。

听说隔壁Rose写了350+行??

code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
struct node
{
char a[5][5];
}list[maxn];
int hash(char a[5][5])
{
int s=0,t=1;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
{
s+=(a[i][j]-'0')*t;
t*=2;
}
return s;
}
char targ[5][5];
bool v[maxn]; int d[maxn];
const int dx[]={1,0,-1,0};
const int dy[]={0,-1,0,1};
int main()
{
for(int i=1;i<=4;i++) scanf("%s",list[1].a[i]+1);
for(int i=1;i<=4;i++) scanf("%s",targ[i]+1);
int st=hash(list[1].a),ed=hash(targ);

memset(d,63,sizeof(d)); d[st]=0;
memset(v,false,sizeof(v)); v[st]=true;
int head=1,tail=2;
while(head!=tail)
{
int x=hash(list[head].a);
node tno=list[head];
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
{
if(tno.a[i][j]==0) continue;
for(int k=0;k<=3;k++)
{
int tx=i+dx[k],ty=j+dy[k];
if(tx<1 || tx>4 || ty<1 || ty>4 || tno.a[tx][ty]=='1') continue;
swap(tno.a[i][j],tno.a[tx][ty]);
int y=hash(tno.a);
if(d[y]>d[x]+1)
{
d[y]=d[x]+1;
if(v[y]==false)
{
v[y]=true;
list[tail++]=tno;
}
}
swap(tno.a[i][j],tno.a[tx][ty]);
}
}
v[x]=false;
head++;
}
printf("%d\n",d[ed]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: