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

    题目描述

    在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态。

    输入输出格式

    输入格式:

    前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。接着是一个空行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。

    输出格式:

    一个整数,所需要的最少移动次数。

    输入输出样例

    输入样例#1: 
    1111
    0000
    1110
    0010 
    
    1010
    0101
    1010
    0101
    输出样例#1: 
    4

    Solution:

      本题比较水,但是我调得快心态炸裂了。(因为变量名的问题,弄错了好几个变量,搞得一直以为手打队列有错,唉~太菜了~!)

      从某一状态转移到另一状态,且给定了转移方法,那么不难想到,一般直接广搜就$OK$了。

      关键如何判重和记录状态,此时由于每个状态是一个$16$位$0/1$字符串,很自然想到了状态压缩:用$1$到$2^{16}=65536$来记录每个状态,爆搜就$AC$了。至于如何转移就直接模拟好了!(本人较蠢,方法比较繁琐,话说手推了一波转移过程,~滑稽~)

    代码:

    #include<bits/stdc++.h>
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    using namespace std;
    const int N=65560;
    int st,ed,op[20],opt,mp[N],ans;
    int dx[17][4]={
        0,0,0,0, 
        1,4,0,0, 
        -1,1,4,0, 
        -1,1,4,0, 
        -1,4,0,0, 
        -4,4,1,0, 
        -1,1,4,-4, 
        -1,1,4,-4,
        -4,4,-1,0,
        -4,4,1,0,
        -1,1,4,-4,
        -1,1,4,-4,
        -4,4,-1,0,
        -4,1,0,0,
        -4,-1,1,0,
        -4,-1,1,0,
        -4,-1,0,0
    };
    queue<int>q;
    char s;
    bool vis[N];
    int main(){
        ios::sync_with_stdio(0);
        For(i,1,16)cin>>s,st=(st<<1)+s-'0';
        For(i,1,16)cin>>s,ed=(ed<<1)+s-'0';
        q.push(st);vis[st]=1;
        while(!q.empty()){
            int u=q.front();q.pop();int p=u;
            if(u==ed)break;
            For(i,1,16){op[17-i]=p%2,p>>=1;}
            For(i,1,16) For(j,0,3)
            if(dx[i][j]!=0){
                if(op[i+dx[i][j]]!=op[i]){
                    swap(op[i+dx[i][j]],op[i]);
                    opt=0;
                    For(k,1,16) opt=(opt<<1)+op[k];
                    if(!vis[opt]){
                        vis[opt]=1,q.push(opt),mp[opt]=mp[u]+1;
                    }
                    swap(op[i+dx[i][j]],op[i]);
                }
            }
        }
        cout<<mp[ed];
        return 0;
    }
  • 相关阅读:
    VB.NET中获取串口列表
    跟着你混,真吃亏!
    [翻译]部署Microsoft .NET Framework Version 3.0(含下载)
    将特定格式的TXT数据文件写入EXCEL
    VB.NET中判断一个数组中是否有重值
    多语言应用程序开发
    .NET 环境下进制间的转换
    初识.NET
    映射Y轴
    Culture Name
  • 原文地址:https://www.cnblogs.com/five20/p/9043026.html
Copyright © 2011-2022 走看看