码迷,mamicode.com
首页 > 移动开发 > 详细

【bzoj1054】[HAOI2008]移动玩具

时间:2017-02-25 11:50:24      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:main   mil   sam   name   题目   题解   ros   style   turn   

题目描述

在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态。

输入

前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。

输出

一个整数,所需要的最少移动次数。

样例输入

1111
0000
1110
0010

1010
0101
1010
0101

样例输出

4


题解

bfs

将状态压成二进制数(应该也可以试一下16维数组),然后bfs搞一搞。

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int q[70000] , l , r , f[70000];
char str[10];
int read()
{
	int i , j , num = 0 , b = 1;
	for(i = 0 ; i < 4 ; i ++ )
	{
		scanf("%s" , str);
		for(j = 0 ; j < 4 ; j ++ )
			num += (str[j] - ‘0‘) * b , b <<= 1;
	}
	return num;
}
int main()
{
	int a , b , u , v , i;
	a = read() , b = read();
	memset(f , -1 , sizeof(f));
	q[0] = a;
	f[a] = 0;
	while(l <= r)
	{
		u = q[l ++ ];
		if(u == b)
		{
			printf("%d\n" , f[u]);
			return 0;
		}
		for(i = 1 ; i <= 16 ; i ++ )
		{
			if(u & (1 << (i - 1)))
			{
				v = u ^ (1 << (i - 1));
				if(i > 4 && (~v) & (1 << (i - 5)) && f[v ^ (1 << (i - 5))] == -1)
					f[v ^ (1 << (i - 5))] = f[u] + 1 , q[++r] = v ^ (1 << (i - 5));
				if(i < 13 && (~v) & (1 << (i + 3)) && f[v ^ (1 << (i + 3))] == -1)
					f[v ^ (1 << (i + 3))] = f[u] + 1 , q[++r] = v ^ (1 << (i + 3));
				if((i - 1) % 4 && (~v) & (1 << (i - 2)) && f[v ^ (1 << (i - 2))] == -1)
					f[v ^ (1 << (i - 2))] = f[u] + 1 , q[++r] = v ^ (1 << (i - 2));
				if(i % 4 && (~v) & (1 << i) && f[v ^ (1 << i)] == -1)
					f[v ^ (1 << i)] = f[u] + 1 , q[++r] = v ^ (1 << i);
			}
		}
	}
	return 0;
}

 

【bzoj1054】[HAOI2008]移动玩具

标签:main   mil   sam   name   题目   题解   ros   style   turn   

原文地址:http://www.cnblogs.com/GXZlegend/p/6441211.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!