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
00101010
0101
1010
0101
Sample Output
4
代码如下
/**************************************************************
Problem: 1054
User: 915759345
Language: C++
Result: Accepted
Time:36 ms
Memory:980 kb
****************************************************************/
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int N=4;
const int f[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
struct xcw{int x,t;};
queue<xcw> que;
bool vis[1<<17];
int Fst=0,Lst=0;
bool readch(){
char ch=getchar();
while(ch^'1'&&ch^'0') ch=getchar();
return ch=='1';
}
int CHG(int x,int y){return 1<<(N*N-(x-1)*N-y);}
bool check(int x,int y){
if(x<1||x>N||y<1||y>N) return 0;
return 1;
}
int BFS(){
que.push((xcw){Fst,0});vis[Fst]=1;
while(!que.empty()){
xcw x=que.front();que.pop();
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++){
int Now=CHG(i,j);
if(Now&x.x){
for(int k=0;k<4;k++){
int fx=i+f[k][0],fy=j+f[k][1],Nxt=0;
if(!check(fx,fy)||(CHG(fx,fy)&x.x)||vis[x.x-Now+CHG(fx,fy)]) continue;
Nxt=x.x-Now+CHG(fx,fy);vis[Nxt]=1;
que.push((xcw){Nxt,x.t+1});
if(Nxt==Lst) return x.t+1;
}
}
}
}
return 0;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("prob.in","r",stdin);
freopen("prob.out","w",stdout);
#endif
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++) Fst=(Fst<<1)+readch();
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++) Lst=(Lst<<1)+readch();
printf("%d\n",BFS());
return 0;
}