码迷,mamicode.com
首页 > 移动开发 > 详细

[HAOI2008] 移动玩具 - BFS

时间:2020-03-06 13:29:40      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:void   signed   std   记忆   cpp   from   turn   ems   状态压缩   

在一个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

标签:void   signed   std   记忆   cpp   from   turn   ems   状态压缩   

原文地址:https://www.cnblogs.com/mollnn/p/12425808.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!