您的位置:首页 > 其它

BZOJ 1054: [HAOI2008]移动玩具 BFS, Hash

2017-01-22 21:49 405 查看
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

解题方法: BZOJ 福利题,8数码问题翻版。。直接上代码。。

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; i++)
map <string, bool> vis;
int tmp[5][5];
int dir[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
bool check(int x, int y){
if(x >= 1 && x <= 4 && y >= 1 && y <= 4) return true;
return false;
}
string hash1(){
string ans = "";
rep(i, 1, 4){
rep(j, 1, 4){
ans += tmp[i][j] + '0';
}
}
return ans;
}
void hash2(string s){
int t = 0;
rep(i, 1, 4){
rep(j, 1, 4){
tmp[i][j] = s[t++] - '0';
}
}
}
struct node{
string status;
int step;
}st, en;
int bfs(){
queue <node> que;
que.push(st);
vis[st.status] = 1;
while(!que.empty()){
node now = que.front(); que.pop();
if(now.status == en.status) return now.step;
hash2(now.status);
rep(i, 1, 4){
rep(j, 1, 4){
if(tmp[i][j] == 1){
rep(k, 0, 4){
int tx = i + dir[k][0];
int ty = j + dir[k][1];
if(!check(tx, ty)) continue;
if(tmp[tx][ty] == 0){
node nxt;
nxt.step = now.step + 1;
swap(tmp[i][j], tmp[tx][ty]);
nxt.status = hash1();
if(!vis[nxt.status]){
vis[nxt.status] = 1;
que.push(nxt);
}
swap(tmp[i][j], tmp[tx][ty]);
}
}
}
}
}
}
return -1;
}
int main(){
string s;
st.step = 0;
rep(i, 1, 4){
cin >> s;
st.status += s;
}
rep(i, 1, 4){
cin >> s;
en.status += s;
}
int ans = bfs();
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: