BZOJ 1054 [HAOI2008]移动玩具
题目描述
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动
时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移
动到某人心中的目标状态。
输入
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空
行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
输出
一个整数,所需要的最少移动次数。
样例输入
1111
0000
1110
0010
1010
0101
1010
0101
样例输出
4
这题看一下就是状压其实,,但是我当时比较蠢,用的dfsT掉了,而我就是傻到没有用bfs,这题可以说是这4题中最水的一个。。。
因为步数不会很多,所以16位bit压一下,bfs水之
code
#include <iostream> #include <cstring> #include <stdio.h> #include <queue> #define ALL (1<<16) using namespace std; int now,to; bool vis[ALL]; typedef pair<int,int>pa; int bfs(){ queue<pa>q; pa x = make_pair(now,0); q.push(x); while(!q.empty()){ pa k = q.front();q.pop(); if(k.first==to)return k.second; if(vis[k.first])continue; vis[k.first]=1; for(int i=0;i<16;i++){ if(((1<<i)&(k.first))==0)continue; if(i-4>=0&&(((k.first)&(1<<(i-4)))==0)){ pa y = k; y.first^=1<<i;y.first|=1<<(i-4); y.second++; if(vis[y.first]==0)q.push(y); } if(i+4<16&&(((k.first)&(1<<(i+4)))==0)){ pa y = k; y.first^=1<<i;y.first|=1<<(i+4); y.second++; if(vis[y.first]==0)q.push(y); } int o = (i+1)%4; if(o!=0&&(((k.first)&(1<<(i+1)))==0)){ pa y = k; y.first^=1<<i;y.first|=1<<(i+1); y.second++; if(vis[y.first]==0)q.push(y); } if(o!=1&&(((k.first)&(1<<(i-1)))==0)){ pa y = k; y.first^=1<<i;y.first|=1<<(i-1); y.second++; if(vis[y.first]==0)q.push(y); } } } return 0; } int main(){ //freopen("movea.in","r",stdin); //freopen("movea.out","w",stdout); for(int i=1;i<=4;i++){ for(int j=1;j<=4;j++){ char ch; cin >> ch; bool x = ch-'0'; if(x)now|=1<<(4*(i-1)+j-1); } } for(int i=1;i<=4;i++) for(int j=1;j<=4;j++){ char ch; cin >> ch; bool x = ch-'0'; if(x)to|=1<<(4*(i-1)+j-1); } printf("%d\n",bfs()); }