zoukankan      html  css  js  c++  java
  • [HAOI2008] 移动玩具

    在一个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];
    }
    
    
  • 相关阅读:
    如何解压.bz2文件包
    Typecho中的gravatar头像无法加载
    整理的mysql优化内容
    PHP常用的一些正则表达式
    git log --stat常用命令
    Linux查找含有某字符串的所有文件
    linux下如何查看chm文件
    linux访问windows共享文件夹的方法
    typecho除了首页其他大部分网页404怎么办?
    Windows在当前目录打开cmd
  • 原文地址:https://www.cnblogs.com/mollnn/p/12425808.html
Copyright © 2011-2022 走看看