• bzoj 1054: [HAOI2008]移动玩具


    状压bfs

    一共有16个位置,最多会有 (2^{16}=65536) 种情况,用数组完全开的下。
    用二进制中的1表示该位置有玩具,0表示该位置没有玩具。
    由于广搜最先搜到的是最优解,直接用数组记录是否到达过该状态,顺便记录ans.
    移动前的状态ans为0.
    然后大力讨论12种情况即可
    时间复杂度O( (2^{16}) )O(能过)
    献上我又臭又长的代码

    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int z[524289],pan[524289];
    int a,b,d;
    char c;
    queue<int>q;
    int ex(int s,int li,int ri)
    {
        return (s^(1<<li))^(1<<ri);
    }
    void fang(int xx,int fa)
    {
        if(pan[xx]==0)
        {
            pan[xx]=1;
            z[xx]=z[fa]+1;
            q.push(xx);
        }
    }
    int main()
    {
        //freopen("toy.in","r",stdin);
        //freopen("toy.out","w",stdout);
        for(int i=1;i<=16;++i)
        {
            cin>>c;
            a=(a<<1)|(c-'0');
        }
        for(int i=1;i<=16;++i)
        {
            cin>>c;
            b=(b<<1)|(c-'0');
        }
        if(a==b)
        {
            cout<<"0";
            return 0;
        }
        pan[a]=1;
        q.push(a);
        while(!q.empty())
        {
            int x=0;
            d=q.front();
            q.pop();
            if(d&(1<<15))//1号位 
            {
                if((d&(1<<14))==0)
                {
                    x=ex(d,15,14);
                    fang(x,d);
                }
                if((d&(1<<11))==0)
                {
                    x=ex(d,15,11);
                    fang(x,d);
                }
            }
            for(int i=2;i<=3;++i)//2~3号位 
            {
                if(d&(1<<(16-i)))
                {
                    if((d&(1<<(16-i+1)))==0)
                    {
                        x=ex(d,16-i,16-i+1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-1)))==0)
                    {
                        x=ex(d,16-i,16-i-1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-4)))==0)
                    {
                        x=ex(d,16-i,16-i-4);
                        fang(x,d);
                    }
                }
            }
            if(d&(1<<12))//4号位 
            {
                if((d&(1<<13))==0)
                {
                    x=ex(d,13,12);
                    fang(x,d);
                }
                if((d&(1<<8))==0)
                {
                    x=ex(d,12,8);
                    fang(x,d);
                }
            }
            if(d&(1<<11))//5号位 
            {
                if((d&(1<<15))==0)
                {
                    x=ex(d,15,11);
                    fang(x,d);
                }
                if((d&(1<<10))==0)
                {
                    x=ex(d,10,11);
                    fang(x,d);
                }
                if((d&(1<<7))==0)
                {
                    x=ex(d,7,11);
                    fang(x,d);
                }
            }
            for(int i=6;i<=7;++i)//6~7号位 
            {
                if(d&(1<<(16-i)))
                {
                    if((d&(1<<(16-i+4)))==0)
                    {
                        x=ex(d,16-i,16-i+4);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i+1)))==0)
                    {
                        x=ex(d,16-i,16-i+1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-1)))==0)
                    {
                        x=ex(d,16-i,16-i-1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-4)))==0)
                    {
                        x=ex(d,16-i,16-i-4);
                        fang(x,d);
                    }
                }
            }
            if(d&(1<<8))//8号位 
            {
                if((d&(1<<12))==0)
                {
                    x=ex(d,8,12);
                    fang(x,d);
                }
                if((d&(1<<9))==0)
                {
                    x=ex(d,8,9);
                    fang(x,d);
                }
                if((d&(1<<4))==0)
                {
                    x=ex(d,8,4);
                    fang(x,d);
                }
            }
            if(d&(1<<7))//9号位 
            {
                if((d&(1<<11))==0)
                {
                    x=ex(d,7,11);
                    fang(x,d);
                }
                if((d&(1<<6))==0)
                {
                    x=ex(d,7,6);
                    fang(x,d);
                }
                if((d&(1<<3))==0)
                {
                    x=ex(d,7,3);
                    fang(x,d);
                }
            }
            for(int i=10;i<=11;++i)//10~11号位 
            {
                if(d&(1<<(16-i)))
                {
                    if((d&(1<<(16-i+4)))==0)
                    {
                        x=ex(d,16-i,16-i+4);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i+1)))==0)
                    {
                        x=ex(d,16-i,16-i+1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-1)))==0)
                    {
                        x=ex(d,16-i,16-i-1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-4)))==0)
                    {
                        x=ex(d,16-i,16-i-4);
                        fang(x,d);
                    }
                }
            }
            if(d&(1<<4))//12号位 
            {
                if((d&(1<<8))==0)
                {
                    x=ex(d,8,4);
                    fang(x,d);
                }
                if((d&(1<<5))==0)
                {
                    x=ex(d,4,5);
                    fang(x,d);
                }
                if((d&(1<<0))==0)
                {
                    x=ex(d,4,0);
                    fang(x,d);
                }
            }
            if(d&(1<<3))//13号位 
            {
                if((d&(1<<7))==0)
                {
                    x=ex(d,3,7);
                    fang(x,d);
                }
                if((d&(1<<2))==0)
                {
                    x=ex(d,3,2);
                    fang(x,d);
                }
            }
            for(int i=14;i<=15;++i)//14~15号位 
            {
                if(d&(1<<(16-i)))
                {
                    if((d&(1<<(16-i+4)))==0)
                    {
                        x=ex(d,16-i,16-i+4);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i+1)))==0)
                    {
                        x=ex(d,16-i,16-i+1);
                        fang(x,d);
                    }
                    if((d&(1<<(16-i-1)))==0)
                    {
                        x=ex(d,16-i,16-i-1);
                        fang(x,d);
                    }
                }
            }
            if(d&(1<<0))//16号位 
            {
                if((d&(1<<1))==0)
                {
                    x=ex(d,0,1);
                    fang(x,d);
                }
                if((d&(1<<4))==0)
                {
                    x=ex(d,4,0);
                    fang(x,d);
                }
            }
        }
        cout<<z[b];
        fclose(stdin);fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    jQuery --checkbox全选和取消全选简洁高效的解决办法
    扩展jquery插件的方法
    git
    varchar,char,varchar2,mybatis查询无返回
    Docker拉取mysql并连接
    Map
    mysql数据库用ip访问
    docker的安装和docket拉取Oracle
    springboot
    linux 安装mysql
  • 原文地址:https://www.cnblogs.com/wljss/p/11482572.html
Copyright © 2020-2023  润新知