[HAOI2008] 移动玩具 - BFS
Posted mollnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HAOI2008] 移动玩具 - BFS相关的知识,希望对你有一定的参考价值。
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态。
Solution
考虑到状态可以被压成一个 (leq 65535) 的数,状态压缩以后暴力记忆化搜索即可
#include <bits/stdc++.h>
using namespace std;
int f[65536];
queue <int> q;
char s[5][5];
int from,to;
int get(int p,int i,int j) {
return (p>>(i*4+j))&1;
}
int put(int p,int i,int j) {
return p|(1<<(i*4+j));
}
int iput(int p,int i,int j) {
return p&(~(1<<(i*4+j)));
}
void solve(int p,int i,int j,int ii,int jj) {
if(ii>=0 && jj>=0 && ii<4 && jj<4 && get(p,ii,jj)==0) {
int t=put(iput(p,i,j),ii,jj);
if(f[t]>f[p]+1) {
f[t]=f[p]+1;
q.push(t);
}
}
}
signed main() {
for(int i=0;i<4;i++) cin>>s[i];
for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(s[i][j]=='1') from=put(from,i,j);
for(int i=0;i<4;i++) cin>>s[i];
for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(s[i][j]=='1') to=put(to,i,j);
q.push(from);
memset(f,0x3f,sizeof f);
f[from]=0;
while(!q.empty()) {
int p=q.front(); q.pop();
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
if(get(p,i,j)) {
solve(p,i,j,i,j-1);
solve(p,i,j,i,j+1);
solve(p,i,j,i-1,j);
solve(p,i,j,i+1,j);
}
}
}
}
cout<<f[to];
}
以上是关于[HAOI2008] 移动玩具 - BFS的主要内容,如果未能解决你的问题,请参考以下文章