1054: [HAOI2008]移动玩具
Time Limit: 10 Sec Memory Limit: 162 MB
Description
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动
时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移
动到某人心中的目标状态。
Input
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空
行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
Output
一个整数,所需要的最少移动次数。
Sample Input
1111
0000
1110
0010
1010
0101
1010
0101
Sample Output
4
HINT
Source
SET判重,BFS轻松水过~
上代码(QAQ很丑的)
#include<iostream>
#include<cstring>
#include <cstdio>
#include <queue>
#include<algorithm>
#include <set>
using namespace std;
set<int>vis;
int xx[5]={0,0,-1,1};
int yy[5]={1,-1,0,0};
bool ans[5][5];
char ch[5];
struct NODE{
bool a[5][5];
int step;
}q[67895];
inline int read(){
int x=0;int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void init(){vis.clear();}
inline bool tr(NODE zhn){
int v=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++){
v=v*10+zhn.a[i][j];
}
if(vis.count(v)) return 0;
vis.insert(v);
return 1;
}
inline bool LHY(int x,int y){
if(x<=0||x>4||y<=0||y>4) return false;
return true;
}
inline void bfs(){
init();
int out;
queue<NODE> f;
f.push(q[1]);
tr(q[1]);
while(!f.empty()){
NODE dmf=f.front();
f.pop();
bool flag=1;
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(dmf.a[i][j]!=ans[i][j]){
flag=0;
break;
}
}
}
if(flag){
out=dmf.step;
break;
}
else{
for(int i=1;i<=4;i++){
for(int j=1;j<=4;j++){
if(dmf.a[i][j]==1){
for(int z=0;z<=3;z++){
int xxx=i+xx[z];
int yyy=j+yy[z];
if(LHY(xxx,yyy)&&(!dmf.a[xxx][yyy])){
dmf.a[xxx][yyy]=1;
dmf.a[i][j]=0;
dmf.step++;
if(tr(dmf))
f.push(dmf);
dmf.a[xxx][yyy]=0;
dmf.a[i][j]=1;
dmf.step--;
}
}
}
}
}
}
}
printf("%d",out);
}
int main(){
for(int i=1;i<=4;i++){
scanf("%s",ch);
for(int j=1;j<=4;j++)
q[1].a[i][j]=ch[j-1]-'0';
}
for(int i=1;i<=4;i++){
scanf("%s",ch);
for(int j=1;j<=4;j++)
ans[i][j]=ch[j-1]-'0';
}
bfs();
return 0;
}