首页 > 代码库 > 【bzoj1054】[HAOI2008]移动玩具
【bzoj1054】[HAOI2008]移动玩具
题目描述
在一个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]移动玩具
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。