【位运算】【BFS】移动玩具

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2246  Solved: 1246
[Submit][Status][Discuss]

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

试题分析:也许太闲的了,我竟然使位运算写这题(一时脑抽)……

               简简单单的BFS,正解再加个HASH搞定

               想想我这样好像还省了个Hash QAQ

代码(大神勿喷)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
//#include<cmath>

using namespace std;
const int INF = 9999999;
#define LL long long

inline int read(){
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
	return x*f;
}
int N,E;
bool vis[65539];
char c;
int l=1,r=1;
struct data{
	int st,k;
}Que[700001];

void BFS(){
	Que[l].st=0,Que[l].k=N;
	int step,Now;
	if(Que[l].k==E){
		printf("%d
",Que[l].st);
		return ;
	}
	while(l<=r){
		Now=Que[l].k,step=Que[l].st;
		for(int i=1;i<=4;i++){
			for(int j=1;j<=4;j++){
				if(((Now>>((4-i)*4+4-j))&1)){
					for(int p=0;p<4;p++){
						if(p==0&&i!=1&&!((Now>>((4-(i-1))*4+4-j))&1)&&!vis[Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+8-j))]){
							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+8-j));
							if(Que[r].k==E){
								printf("%d
",step+1);
								return ;
							}
							Que[r].st=step+1;
							vis[Que[r].k]=1;
						}
						if(p==1&&i!=4&&!((Now>>((4-(i+1))*4+4-j))&1)&&!vis[Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4-j))]){
							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4-j));
							if(Que[r].k==E){
								printf("%d
",step+1);
								return ;
							}
							Que[r].st=step+1;
							vis[Que[r].k]=1;
						}
						if(p==2&&j!=1&&!((Now>>((4-i)*4+4-(j-1)))&1)&&!vis[(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j-1)))]){
							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j-1)));
							if(Que[r].k==E){
								printf("%d
",step+1);
								return ;
							}
							Que[r].st=step+1;
							vis[Que[r].k]=1;
						}
						if(p==3&&j!=4&&!((Now>>((4-i)*4+4-(j+1)))&1)&&!vis[Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j+1)))]){
							Que[++r].k=Now-(1<<((4-i)*4+4-j))+(1<<((4-i)*4+4-(j+1)));
							if(Que[r].k==E){
								printf("%d
",step+1);
								return ;
							}
							Que[r].st=step+1;
							vis[Que[r].k]=1;
						}
					}
				}
			}
		}
		
		l++;
	}
}

int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	int tmp=16;
	for(int i=1;i<=4;i++)
	    for(int j=1;j<=4;j++){
	    	cin>>c;
	    	N=N+(1<<(tmp-1))*(c-'0');
	    	tmp--;
		}
	vis[N]=true;
	tmp=16;
	for(int i=1;i<=4;i++)
	    for(int j=1;j<=4;j++){
	    	cin>>c;
	    	E=E+(1<<(tmp-1))*(c-'0');
	    	tmp--;
		}
	BFS();
	return 0;
}