3856 - 移动玩具
时间限制 : 1 秒
内存限制 : 128 MB
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态。
题目输入
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。
接着是一个空行。
接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
题目输出
一个整数,所需要的最少移动次数。
输入/输出样例
输入格式
1111 0000 1110 0010 1010 0101 1010 0101
输出格式
4
C++解答
#define MAXN 80010UL #define MAXS 5UL #include <cstdio> #include <queue> #include <cstring> int dx[MAXN],Map_now[MAXS][MAXS],dream[MAXS][MAXS]; char inp[MAXS<<1];std::queue<int> que;bool ex[MAXN]; int opx[4]={0,0,1,-1}; int opy[4]={1,-1,0,0}; inline int Pos(int x,int y){ return ((x-1)<<2)+y-1; } inline int Cal(int p[5][5]){ int Ans=0; for(int i=1;i<5;i++) for(int j=1;j<5;j++) if(p[i][j]) Ans|=1<<Pos(i,j); return Ans; } int main(){ for(int i=1;i<5;i++){scanf("%s",inp+1);for(int j=1;j<5;j++) Map_now[i][j]=inp[j]-'0';} for(int i=1;i<5;i++){scanf("%s",inp+1);for(int j=1;j<5;j++) dream[i][j]=inp[j]-'0';} memset(dx,50,sizeof(dx));int stat;dx[stat=Cal(Map_now)]=0;que.push(stat); while(!que.empty()){ int p=que.front(),new_s;que.pop();ex[p]=false; for(int i=1;i<5;i++){ for(int j=1;j<5;j++){ int new_p=Pos(i,j); if(p&(1<<new_p)){ for(int k=0;k<4;k++){ int nx=i+opx[k],ny=j+opy[k]; int rp=Pos(nx,ny); if(nx<1||nx>4) continue; if(ny<1||ny>4) continue; if((p&(1<<rp))==0){ new_s=p;new_s^=1<<new_p; new_s|=1<<rp; if(dx[new_s]>dx[p]+1){ dx[new_s]=dx[p]+1; if(!ex[new_s]){ ex[new_s]=true; que.push(new_s); } } } } } } } } printf("%d",dx[Cal(dream)]); return 0; }