1742: [Usaco2005 nov]Grazing on the Run
1706: [usaco2007 Nov]relays

1054: [HAOI2008]移动玩具

高橋直樹 posted @ 2013年3月20日 10:21 in BZOJ with tags bzoj HAOI , 1036 阅读

http://www.lydsy.com/JudgeOnline/problem.php?id=1054

RunID User Problem Result Memory Time Language Code_Length Submit_Time
371808 Liu_Ts 1054 Accepted 1316 kb 16 ms C++ 1000 B 2013-03-19 19:10:37

 

大意

在一个4*4的方框内摆放了若干个相同的玩具,将这些玩具重新摆放成为理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具。求最小移动次数。

题解

暴力BFS,因为格子很少,直接用位运算

萌神的写法非常厉害,看代码吧。

 

#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=65536,
dx[24]={15,14,13,15,14,13,12,11,10,9,11,10,9,8,7,6,5,7,6,5,4,3,2,1},
dy[24]={14,13,12,11,10,9,8,10,9,8,7,6,5,4,6,5,4,3,2,1,0,2,1,0};
int q[N],d[N],S,T;

int main()
{
	memset(d,127,sizeof(d));
	for(int i=0;i<4;i++,getchar())
		for(int j=0;j<4;j++)
			S=(S<<1)+getchar()-'0';
	getchar();
	for(int i=0;i<4;i++,getchar())
		for(int j=0;j<4;j++)
			T=(T<<1)+getchar()-'0';
	if(S==T){puts("0");return 0;}
	d[S]=0;int l=0,r=1;q[1]=S;
	while(l<r)
	{
		int now=q[++l];
		for(int i=0;i<24;i++)
		{
			int x=now&(1<<dx[i]),y=now&(1<<dy[i]);
			int next=now-x-y;
			if(x)	next+=1<<dy[i];
			if(y)	next+=1<<dx[i];
			if(d[next]>d[now]+1)
			{
				d[next]=d[now]+1;
				q[++r]=next;
				if(next==T)
				{
					printf("%d\n",d[T]);
					return 0;
				}
			}
		}
	}
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter