• 状态压缩


    定义

    状态压缩,实际上是将一个30左右长度的bool数组用一个int来表示。为什么呢?众所周知,bool类型只有0,1两种两种类型。而计算机又是用二进制来存储数字,加之强大的位运算功能,我们便可以更改整数在二进制下表示的每一位的数字,来表示不同的状态。由于其与位运算密切相关,所以我们先来讨论一下位运算的事情。

    位运算

    不做演示,可以自行演示验证

    S是原集合

    S&(1<<(k-1))   取出第k位
     ^             将第k位取反
     |             将第k位强制变1
    S^(1<<k-1)       取补集 
    S&(-S)         取出右起第一个1  ,减掉这个结果数就更新状态 lowbit
    S|A==S         A是S的子集
    for(x=s;x;s&(x-1)  枚举子集

    题目中的ShowTime

    开关游戏

     何以状态压缩?唯开关亮灭与否也!

    开关矩阵是4*4,所以状态数只有16个,完全可以状态压缩

    然后通过宽搜枚举每个按键,注意通过位运算判断边界情况。

    一定要记得先判断是否初始状态已经全部亮起或全部熄灭。

    #include<iostream>
    #include<cmath>
    #include<queue>
    using namespace std;
    const int MAXN=65536;
    int start;
    int Pow[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,8192,16384};
    bool Appear[MAXN];
    int step[MAXN];
    queue<int> Q;
    int ans;
    int click(int h,int i){
        h^=(1<<i);
        if((i)%4!=0){
            h^=(1<<(i-1));
        }
        if((i+1)%4!=0){
            h^=(1<<(i+1));
        }
        if(i>=4){
            h^=(1<<(i-4));
        }
        if(i<=11){
            h^=(1<<(i+4));
        }
        return h;
    }
    int bfs(){
        Q.push(start);
        step[start]=0;
        Appear[start]=true;
        while(!Q.empty()){
            int h=Q.front();
            Q.pop();
            for(int i=0;i<=15;i++){
                int st=click(h,i);
                if(!Appear[st]){
                    if(st==0||st==65535){
                        return step[h]+1;
                        
                    }
                        Appear[st]=true;
                        Q.push(st);
                        step[st]=step[h]+1;
                }
            }
        }
        cout<<"Impossible";
        return 0;
    }
    int main(){
    //   int p=16; 
    //    while(p>0){ 
    //        char ch=getchar(); 
    //        if(ch=='w'||ch=='b'){ 
    //            if(ch=='w')start+=(1<<(p-1)); 
    //            p--; 
    //        } 
    //    } 
        for(int i=15;i>=0;i--){
            char ch=getchar();
            if(ch=='w'||ch=='b'){
                if(ch=='w')start+=(1<<(i));
            }
            else{
                i++;
            }
        }
        if(start==65535||start==0){
            cout<<0;
            return 0;
        }
        ans=bfs();
        if(!ans){
            //cout<<"Impossible";
        }
        else{
            cout<<ans;
        }
            
    }
  • 相关阅读:
    当前日志损坏解决一例
    Oracle 1204 RAC failover 测试 (一)
    Logical standby跳过个别SQL不Apply的测试
    Data guard 又出问题了
    CPIO无反应
    回答棉花糖先生关于我说的DB自动增加Index的问题
    SSD硬盘,先不要用在Server上
    ORA00304: requested INSTANCE_NUMBER is busy,终于解决
    .Net运行时的相互关系
    CSS布局探密04
  • 原文地址:https://www.cnblogs.com/Uninstalllingyi/p/11432672.html
Copyright © 2020-2023  润新知