zoukankan      html  css  js  c++  java
  • 洛谷 P2622 关灯问题II (状态压缩+BFS)

    题目描述
    现有n盏灯,以及m个按钮。每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果。按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时候,把它关上,否则不管;如果为-1的话,如果这盏灯是关的,那么把它打开,否则也不管;如果是0,无论这灯是否开,都不管。

    现在这些灯都是开的,给出所有开关对所有灯的控制效果,求问最少要按几下按钮才能全部关掉。

    输入输出格式
    输入格式:
    前两行两个数,n m

    接下来m行,每行n个数,a[i][j]表示第i个开关对第j个灯的效果。

    输出格式:
    一个整数,表示最少按按钮次数。如果没有任何办法使其全部关闭,输出-1

    输入输出样例
    输入样例#1:
    3
    2
    1 0 1
    -1 1 0
    输出样例#1:
    2
    说明
    对于20%数据,输出无解可以得分。

    对于20%数据,n<=5

    对于20%数据,m<=20

    上面的数据点可能会重叠。

    对于100%数据 n<=10,m<=100

    题意:

    思路:

    用一个int类型的整数state 来记录当前灯泡的状态, 二进制来描述信息
    state 的第i位为1,表示第i个灯泡现在是亮的,否则是灭掉的。
    然后暴力去跑BFS, 同时用一个数组VIS标记哪些状态被访问了,而利用bfs的性质,后面一个状态state,如果 vis[state] =1 表明在前面被访问过了,那么这一个就可以忽略了,因为前面的步数step一定小于等于当前的step.

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n,m;
    bool flag=1;
    int a[105][105];
    int ans=inf;
    struct node
    {
        int state;
        int step;
        node(){}
        node(int st,int sstep)
        {
            state=st;
            step=sstep;
        }
    };
    queue<node> q;
    int vis[2500];
    void bfs()
    {
        int num=0;
        for(int i=1;i<=n;i++)
        {
            num|=(1<<i);
        }
        q.push(node(num,0));
        node temp;
        int cnt=0;
        while(flag&&!q.empty())
        {
            temp=q.front();
            q.pop();
            cnt++;
            if(temp.state==0)
            {
                ans=min(ans,temp.step);
                flag=0;
                break;
            }
            for(int i=1;i<=m;i++)
            {
                num=temp.state;
                for(int j=1;j<=n;j++)
                {
                    if (a[i][j]==1)
                    {
                        if((num&(1<<j))>0)
                        {
                            num-=(1<<j);
                        }
                    }else if(a[i][j]==-1)
                    {
                        if((num&(1<<j))==0)
                        {
                            num+=(1<<j);
                        }
                    }
                }
                if(!vis[num])
                {
                    q.push(node(num,temp.step+1));
                    vis[num]=1;
                }
            }
        }
    
    }
    int main()
    {
        // freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:common_textcode_streamout.txt","w",stdout);
        gbtb;
        // cout<<(1<<10)<<endl;
        cin>>n>>m;
        repd(i,1,m)
        {
            repd(j,1,n)
            {
                cin>>a[i][j];
            }
        }
        bfs();
        if(ans==inf)
        {
            ans=-1;
        }
        cout<<ans<<endl;
        
        
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    source insight 4.0.086破解
    Java IO流关闭问题的深入研究
    iOS开发UI篇—UITableview控件使用小结
    iOS开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
    iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
    iOS开发UI篇—实现UItableview控件数据刷新
    iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序
    iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)
    iOS开发UI篇—UITableviewcell的性能优化和缓存机制
    iOS开发UI篇—UITableview控件基本使用
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11146645.html
Copyright © 2011-2022 走看看