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 MBSubmit: 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
0000
1110
0010
1010
0101
1010
0101
Sample Output
4