zoukankan      html  css  js  c++  java
  • POJ 1176 Party Lamps (DFS)

    对于一束灯光。提供四种改变彩灯状态(ON<=>OFF)的操作:a.改变全部彩灯状态;b.改变奇数彩灯状态。c.改变偶数彩灯状态;d.改变3k+1号彩灯状态(1,4,7,10...)。

     给定彩灯数目。操作次数,和对于某几个彩灯必须为ON、某几个彩灯必须为OFF的要求,问经过给定次数的操作,终于能达到的满足要求的状态有多少种,输出全部满足要求的彩灯状态。

     原题中操作次数是1<=C<=10000的。假设以此为搜索深度。未免比較可怕。还好这里有点小玄机,能够将搜索次数大大限制。

    考虑那四个操作,能够发现有这种特点:

     1.操作序列中的各操作是能够交换的。即ab=ba;

    2.每两次同样操作效果抵消,即aab=b。

     能够将将偶数个同样操作消除,奇数个同样操作剩余一个就可以,得到一个小于等于4个操作的操作序列,当中每一个操作不多于一次。

    据此处理一个操作序列,首先将全部同样的操作归并到一起。得到aa...ab....bc....cd....d的序列;然后将偶数个同样操作消除,奇数个同样操作剩余一个就可以,得到一个小于等于4个操作的操作序列,当中每一个操作不多于一次。

    所以能够将操作数限制在4下面,4^4=256,一共同拥有256种终于状态,暴搜就可以。以4层搜索为例,每层搜索中求解彩灯状态建立在上层搜索的结果状态上。用一个线性数组存储全部层次结果的话,须要建立起下层结果和上层结果在存储位置上的相应方式。因为每次搜索将结果数扩张四倍,所以得到相应关系为i = (j-1)/4。

    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<stdlib.h>
    using namespace std;
    int N;
    int C;
    int a[101];
    int _open[101];
    int _close[101];
    string ss[300];
    void do1()
    {
        for(int i=1;i<=100;++i)
            a[i]^=1;
    }
    void do2()
    {
        for(int i=2;i<=N;i+=2)
            a[i]^=1;
    }
    void do3()
    {
        for(int i=1;i<=N;i+=2)
            a[i]^=1;
    }
    void do4()
    {
        for(int i=1;i<=N;i+=3)
            a[i]^=1;
    }
    int cnt=0;
    int check()
    {
        for(int i=1;i<=N;++i){
            if(_open[i]==1&&a[i]==0)return 1;
            if(_close[i]==1&&a[i]==1)return 1;
        }
        return 0;
    }
    void dfs(int c)
    {
        if(c==C)
        {
            if(check()==0)
            {
                ss[cnt]="";
                for(int i=0; i<N; i++)
                    ss[cnt]+=(a[i+1]+'0');
                cnt++;
            }
            return;
        }
        for(int i=1;i<=4;++i)
        {
            switch(i)
            {
            case 1:
                do1();//开关一次
                dfs(c+1);
                do1();//再开关一次还原回来
                break;
            case 2:
                do2();
                dfs(c+1);
                do2();
                break;
            case 3:
                do3();
                dfs(c+1);
                do3();
                break;
            case 4:
                do4();
                dfs(c+1);
                do4();
                break;
            }
        }
    }
    int main(int argc, char *argv[])
    {
        //   freopen("1176.in","r",stdin);
        scanf("%d",&N);
        scanf("%d",&C);
        memset(_open,0,sizeof(_open));
        memset(_close,0,sizeof(_close));
        for(int i=1;i<=N;++i)
            a[i]=1;
        int tmp;
        while(scanf("%d",&tmp)==1&&tmp!=-1)
            _open[tmp]=1;
        while(scanf("%d",&tmp)==1&&tmp!=-1)
            _close[tmp]=1;
        if(C>4)
        {
            C%=2;
            if (C==1)
            {
                C=3;
            }
            else
            {
                C=4;
            }
        }
        dfs(0);
        sort(ss,ss+cnt);
        cout<<ss[0]<<endl;
        int i,j;
        for(i=0,j=1;j<cnt;j++)
            if(ss[i]!=ss[j])
            {
                i=j;
                cout<<ss[i]<<endl;
            }
    
        return 0;
    }
    


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    关于这个 blog
    P6499 [COCI2016-2017#2] Burza 题解
    CF1172F Nauuo and Bug 题解
    CF1479D Odd Mineral Resource 题解
    CF1442E Black, White and Grey Tree 题解
    CF1442D Sum 题解
    CF1025D Recovering BST 题解
    CF1056E Check Transcription 题解
    CF1025F Disjoint Triangles 题解
    红包算法的PHP实现
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4747580.html
Copyright © 2011-2022 走看看