题目描述
在一个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
",bfs());
}