【BZOJ1054】[HAOI2008]移动玩具 BFS

【BZOJ1054】[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

题解:把4x4矩阵压成16位的二进制数,然后跑BFS

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
char str[10];
int s,t,u,v;
int d[1<<16],w[]={1,-1,4,-4};
queue<int> q;
void move(int i)
{
	if(v&(1<<i))	return ;
	int x=v+(1<<i);
	if(d[x])	return ;
	d[x]=d[u]+1;
	q.push(x);
}
int main()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		scanf("%s",str);
		for(j=0;j<4;j++)	s=s*2+str[j]-'0';
	}
	for(i=0;i<4;i++)
	{
		scanf("%s",str);
		for(j=0;j<4;j++)	t=t*2+str[j]-'0';
	}
	q.push(s);
	d[s]=1;
	while(!q.empty())
	{
		u=q.front(),q.pop();
		for(i=0;i<16;i++)
		{
			if((1<<i)&u)
			{
				v=(1<<i)^u;
				if(i%4>0)	move(i-1);
				if(i%4<3)	move(i+1);
				if(i/4>0)	move(i-4);
				if(i/4<3)	move(i+4);
				if(d[t])
				{
					printf("%d",d[t]-1);
					return 0;
				}
			}
		}
	}
}
posted @ 2017-02-25 10:59  CQzhangyu  阅读(394)  评论(0编辑  收藏  举报