1054: [HAOI2008]移动玩具
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
双向BFS即可。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 10 14 #define maxm 10000+5 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int a[maxn][maxn],b[maxn][maxn],now[maxn][maxn],s[2][140000],flag,ans,h[2],t[2],q[2][140000]; 30 bool book[2][140000]; 31 void init(int t[maxn][maxn]){ 32 for1(i,4) 33 for1(j,4){ 34 char ch=getchar(); 35 while(ch<'0'||ch>'9')ch=getchar(); 36 t[i][j]=ch-'0'; 37 } 38 } 39 int hash(int t[maxn][maxn]){ 40 int tmp=0; 41 for1(i,4) 42 for1(j,4){ 43 tmp<<=1; 44 tmp=tmp|t[i][j]; 45 } 46 return tmp; 47 } 48 void work(int k,int r[maxn][maxn],int w){ 49 int tmp=hash(r); 50 if(book[k][tmp]==0){ 51 book[k][tmp]++; 52 s[k][tmp]=w+1; 53 q[k][++t[k]]=tmp; 54 } 55 if(book[k^1][tmp]){ 56 flag=1;ans=s[k^1][tmp]+s[k][tmp]; 57 return; 58 } 59 } 60 void bfs(int k){ 61 memset(now,0,sizeof(now)); 62 int x=q[k][++h[k]],w=s[k][x]; 63 for(int i=4;i>0;i--) 64 for(int j=4;j>0;j--){ 65 now[i][j]=x&1; 66 x>>=1; 67 } 68 for1(i,4) 69 for1(j,4){ 70 if(i!=1&&now[i-1][j]!=now[i][j]){ 71 now[i][j]^=1;now[i-1][j]^=1; 72 work(k,now,w);if(flag)return; 73 now[i][j]^=1;now[i-1][j]^=1; 74 } 75 if(i!=4&&now[i+1][j]!=now[i][j]){ 76 now[i][j]^=1;now[i+1][j]^=1; 77 work(k,now,w);if(flag)return; 78 now[i][j]^=1;now[i+1][j]^=1; 79 } 80 if(j!=1&&now[i][j-1]!=now[i][j]){ 81 now[i][j]^=1;now[i][j-1]^=1; 82 work(k,now,w);if(flag)return; 83 now[i][j]^=1;now[i][j-1]^=1; 84 } 85 if(j!=4&&now[i][j+1]!=now[i][j]){ 86 now[i][j]^=1;now[i][j+1]^=1; 87 work(k,now,w);if(flag)return; 88 now[i][j]^=1;now[i][j+1]^=1; 89 } 90 } 91 } 92 int main(){ 93 //freopen("input.txt","r",stdin); 94 //freopen("output1.txt","w",stdout); 95 init(a);init(b); 96 work(0,a,-1);work(1,b,-1); 97 h[0]=h[1]=0; 98 while(h[0]<t[0]||h[1]<t[1]){ 99 if(h[1]==t[1])bfs(0); 100 if(flag)break; 101 if(h[0]==t[0])bfs(1); 102 if(flag)break; 103 if(t[1]-h[1]<t[0]-h[0])bfs(1);else bfs(0); 104 if(flag)break; 105 } 106 printf("%d",ans); 107 return 0; 108 }