• 关灯问题II


    洛咕

    题意:现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果。按下i按钮对于第j盏灯,是下面3中效果之一:如果(a[i][j])(1),那么当这盏灯开了的时候,把它关上,否则不管;如果为(-1)的话,如果这盏灯是关的,那么把它打开,否则也不管;如果是(0),无论这灯是否开,都不管.现在这些灯都是开的,给出所有开关对所有灯的控制效果,求问最少要按几下按钮才能全部关掉.(n<=10,m<=100).

    分析:(n<=10),直接用十位二进制数表示灯的状态,1为开,0为关,然后跑(bfs)即可,初始状态为全(1),每一步扩展直接枚举(m)种方式,能转移就转移.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    int a[105][15],f[1050];
    queue<int>q;
    int main(){
    	int n=read(),m=read();
    	for(int i=1;i<=m;++i)
    		for(int j=1;j<=n;++j)a[i][j]=read();
    	for(int i=0;i<(1<<n)-1;++i)f[i]=1e9;f[(1<<n)-1]=0;
    	q.push((1<<n)-1);
    	while(q.size()){
    		int u=q.front();q.pop();
    		for(int i=1;i<=m;++i){
    			int v=u;
    			for(int j=1;j<=n;++j){
    				if(a[i][j]==-1)v|=1<<(j-1);
    				if(a[i][j]==1)if(v&(1<<(j-1)))v^=1<<(j-1);
    			}
    			if(f[v]==1e9)f[v]=f[u]+1,q.push(v);
    		}
    	}
    	if(f[0]==1e9)puts("-1");
    	else printf("%d
    ",f[0]);
    	return 0;
    }
    
    
  • 相关阅读:
    linux 用户与用户组
    linux 用户管理、权限管理
    linux服务与进程
    linux 磁盘阵列
    linux 文件系统 磁盘分区 格式化
    linux shell基础
    Linux网络设置
    DNS域名服务器配置
    Arduino 各种模块篇 摇杆模块
    Arduino 不同Arduino衍生板子的问题
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11723882.html
Copyright © 2020-2023  润新知