bzoj1054: [HAOI2008]移动玩具

hash+bfs;要注意特殊情况。(似乎连sort。lower_bound都不用数据小直接判重了。。。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define REP(i,s,t) for(int i=s;i<=t;i++)
struct node{
	int a[5][5];int dist;
};
node A,B,q[65540];
char tmp[5];
int xx[5]={0,0,0,1,-1};
int yy[5]={0,1,-1,0,0};
bool vis[65540];
int get(node x){
	int k=1,ans=0;
	rep(i,4) rep(j,4) {
		if(x.a[i][j]) ans+=k;
		k<<=1;
	}
	return ans;
}
void init(){
	rep(i,4){
		scanf("%s",tmp);
		rep(j,4) A.a[i][j]=tmp[j-1]-'0';
	}
	rep(i,4){
		scanf("%s",tmp);
		rep(j,4) B.a[i][j]=tmp[j-1]-'0';
		B.dist=0;
	}
}
void work(){
	clr(vis,false);
	int s=get(A),t=get(B);
	if(s==t){
		printf("0\n");return ;
	}
	int l=1,r=1;q[1]=B;
	while(l<=r){
		node x=q[l];
		rep(i,4) rep(j,4) if(x.a[i][j]) rep(k,4){
			int tx=i+xx[k],ty=j+yy[k];
			if(!tx||!ty||tx>4||ty>4||x.a[tx][ty]) continue;
			swap(x.a[i][j],x.a[tx][ty]);
			x.dist++;
			int temp=get(x);
			if(!vis[temp]){
				if(temp==s) {
					printf("%d\n",x.dist);
					return ;
				}
				vis[temp]=1;q[++r]=x;
			}
			swap(x.a[i][j],x.a[tx][ty]);x.dist--;
		}
		l++;
	}
}
int main(){
	init();work();return 0;
}

  

1054: [HAOI2008]移动玩具

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1764  Solved: 972
[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

 
[Submit][Status][Discuss]
posted @ 2016-07-16 22:03  BBChq  阅读(228)  评论(0编辑  收藏  举报