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

    题目大意:

      给你两个4*4的01矩阵A、B,要求你从矩阵A中将'1'移动若干步(移动即与相邻的'0'交换位置),变换为B,输出最小步数.

    基本思路:

      本题数据较小,固定为4*4,第一时间想到状压(2^16),用状压代替hash比较容易.由于要求最小步数,bfs扫描到B矩阵即可输出答案,复杂度远小于dfs.

    code:

      

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define R register
    #define next exnt
    #define debug puts("mlg")
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writesp(ll x);
    inline void writeln(ll x);
    ll ans[65536],n,goal;
    bool d[5][5];
    inline ll calc(bool M[5][5]){
        ll sum=0;
        for(R ll i=1;i<=16;i++) if(M[(i-1)/4+1][(i-1)%4+1]) sum+=1<<i-1;
        return sum;
    }
    queue<ll>q;
    inline void Bfs(ll now){
        ll To;
        q.push(now);
        while(q.size()){
            now=q.front();q.pop();
            if(now==goal){
                writeln(ans[now]);exit(0);
            }
            for(R ll i=1;i<=16;i++) d[(i-1)/4+1][(i-1)%4+1]=(now&(1<<i-1));
            for(R ll i=1;i<=4;i++){
                for(R ll j=1;j<=4;j++){
                    if(d[i][j]){
                        if(i-1>0&&!d[i-1][j]){
                            swap(d[i-1][j],d[i][j]);
                            To=calc(d);
                            if(ans[To]>ans[now]+1){
                                ans[To]=ans[now]+1;
                                q.push(To);
                            }
                            swap(d[i-1][j],d[i][j]);
                        }
                        if(i+1<5&&!d[i+1][j]){
                            swap(d[i+1][j],d[i][j]);
                            To=calc(d);
                            if(ans[To]>ans[now]+1){
                                ans[To]=ans[now]+1;
                                q.push(To);
                            }
                            swap(d[i+1][j],d[i][j]);
                        }
                        if(j-1>0&&!d[i][j-1]){
                            swap(d[i][j-1],d[i][j]);
                            To=calc(d);
                            if(ans[To]>ans[now]+1){
                                ans[To]=ans[now]+1;
                                q.push(To);
                            }
                            swap(d[i][j-1],d[i][j]);
                        }
                        if(j+1<5&&!d[i][j+1]){
                            swap(d[i][j+1],d[i][j]);
                            To=calc(d);
                            if(ans[To]>ans[now]+1){
                                ans[To]=ans[now]+1;
                                q.push(To);
                            }
                            swap(d[i][j+1],d[i][j]);
                        }
                    }    
                }
            }
        }
    }
    int main(){
        for(R ll i=1,x;i<=16;i++){
            char c=getchar();
            while(c!='0'&&c!='1') c=getchar();
            x=c-'0';
            if(x) n+=1<<i-1;
        }
        memset(ans,0x3f,sizeof ans);
        for(R ll i=1,x;i<=16;i++){
            char c=getchar();
            while(c!='0'&&c!='1') c=getchar();
            x=c-'0';
            if(x) goal+=1<<i-1;
        }
        ans[n]=0;
        Bfs(n);
    }
    inline ll read(){
        ll x=0,t=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-') t=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*t;
    }
    inline void write(ll x){
        if(x<0){putchar('-');x=-x;}
        if(x<=9){putchar(x+'0');return;}
        write(x/10);putchar(x%10+'0');
    }
    inline void writesp(ll x){
        write(x);putchar(' ');
    }
    inline void writeln(ll x){
        write(x);putchar('
    ');
    }
  • 相关阅读:
    bzoj 1407: [Noi2002]Savage【扩展欧几里得+中国剩余定理】
    bzoj 2142: 礼物【中国剩余定理+组合数学】
    BSGS
    bzoj 2242: [SDOI2011]计算器【扩展欧几里得+快速幂+BSGS】
    bzoj 3122: [Sdoi2013]随机数生成器【BSGS】
    bzoj 3239: Discrete Logging && 2480: Spoj3105 Mod【BSGS】
    bzoj 1180: [CROATIAN2009]OTOCI【LCT】
    51nod 1122 机器人走方格 V4 【矩阵快速幂】
    51nod 1120 机器人走方格 V3 【卡特兰数+卢卡斯定理+组合数】
    51nod 1119 机器人走方格 V2 【组合数学】
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13307474.html
Copyright © 2011-2022 走看看