bzoj 1054: [HAOI2008]移动玩具 bfs
1054: [HAOI2008]移动玩具
Time Limit: 10 Sec Memory Limit: 162 MB[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
#include<bits/stdc++.h> using namespace std; #define ll long long #define pi (4*atan(1.0)) #define eps 1e-14 const int N=2e5+10,M=1e6+10,inf=1e9+10,mod=1e9+7; const ll INF=1e18+10; struct is { char a[5][5]; int step; }; char mp[5][5]; char ans[5][5]; map<string,int>m; string check(char mp[][5]) { string a=""; for(int i=0;i<4;i++) for(int t=0;t<4;t++) a+=mp[i][t]; return a; } queue<is>q; int ff(int x,int y) { if(x<0||x>=4||y<0||y>=4) return 0; return 1; } int xx[4]={0,1,0,-1}; int yy[4]={1,0,-1,0}; int main() { for(int i=0;i<4;i++) scanf("%s",mp[i]); for(int i=0;i<4;i++) scanf("%s",ans[i]); m[check(mp)]=1; is f; for(int i=0;i<4;i++) for(int t=0;t<4;t++) f.a[i][t]=mp[i][t]; f.step=0; q.push(f); int out; while(!q.empty()) { is b=q.front(); q.pop(); int flag=1; for(int i=0;i<4;i++) { for(int t=0;t<4;t++) if(b.a[i][t]!=ans[i][t]) { flag=0; break; } } if(flag) { out=b.step; break; } for(int i=0;i<4;i++) { for(int t=0;t<4;t++) if(b.a[i][t]=='1') { for(int j=0;j<4;j++) { int xxx=i+xx[j]; int yyy=t+yy[j]; //cout<<xxx<<" "<<yyy<<" "<<ff(xxx,yyy)<<endl; if(ff(xxx,yyy)&&b.a[xxx][yyy]=='0') { b.a[xxx][yyy]='1'; b.a[i][t]='0'; b.step++; if(m[check(b.a)]==0) q.push(b),m[check(b.a)]=1; b.step--; b.a[xxx][yyy]='0'; b.a[i][t]='1'; } } } } } printf("%d\n",out); return 0; }