题目描述

现有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\n",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), '\0', 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_text\code_stream\out.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 == '\n');
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';
}
}
}

洛谷 P2622 关灯问题II (状态压缩+BFS)的更多相关文章

  1. 洛谷 P2622 关灯问题II【状压DP;隐式图搜索】

    题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...

  2. 洛谷P2622 关灯问题II

    洛谷题目链接 声明: 本篇文章不讲基础,对萌新不太友好,(我就是萌新),要学状压$dp$的请另寻,这篇文章只是便于本人查看.... 首先看到$n<=10$,就可以考虑状压了,要求最小值,所以初始 ...

  3. P2622 关灯问题II (状态压缩入门)

    题目链接: https://www.luogu.org/problemnew/show/P2622 具体思路:暴力,尝试每个开关,然后看所有的情况中存不存在灯全部关闭的情况,在储存所有灯的情况的时候, ...

  4. P2622 关灯问题II (状态压缩,最短路)

    题目链接 Solution 这道题算是很经典的状压问题了,好题. 考虑到 \(n\) 的范围仅为 \(10\) , 那么也就是说所有状态压起来也只有 \(1024\) 种情况. 然后我们发现 \(m\ ...

  5. 洛谷 P2622 关灯问题II【状压DP】

    传送门:https://www.luogu.org/problemnew/show/P2622 题面: 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的 ...

  6. 洛谷 P2622 关灯问题II(状压DP入门题)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int n,m; ];//a[i][j] : 第i个开关对第j个 ...

  7. 洛谷P2622 关灯问题II (二进制枚举+bfs

    题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...

  8. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

  9. 洛谷P1433 吃奶酪 题解 状态压缩DP

    题目链接:https://www.luogu.com.cn/problem/P1433 题目大意 房间里放着 \(n\) 块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 \((0, ...

随机推荐

  1. Python深度学习读书笔记-2.初识神经网络

    MNIST 数据集 包含60 000 张训练图像和10 000 张测试图像,由美国国家标准与技术研究院(National Institute of Standards and Technology,即 ...

  2. 中国MOOC_零基础学Java语言_第7周 函数_2完数

    2 完数(5分) 题目内容: 一个正整数的因子是所有可以整除它的正整数.而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数.例如6=1+2+3(6的因子是1,2,3). 现在,你要写一个程序, ...

  3. malloc和cmalloc

    void *malloc(size_t size); 分配内存,但不会初始化,未使用内存不一定是0: void *calloc(size_t numElements,size_t sizeOfElem ...

  4. 6.824 Lab 2: Raft 2C

    Part 2C Do a git pull to get the latest lab software. If a Raft-based server reboots it should resum ...

  5. ES6标准入门 第三章:变量的解构赋值

    解构赋值:从数组和对象中提取值,对变量进行赋值. 本质上,这种写法属于“匹配模式”:只要等号两边的模式相同,左边的变量就会被赋予对应的值. 1.数组的结解构赋值 基本用法 let [foo, [[ba ...

  6. Android Studio编译报错Could not reserve enough space for 2097152KB object heap解决方法

    环境变量中添加

  7. 【MM系列】SAP MM模块-打开前面物料账期的方法

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]在SAP里查看数据的方法   前言部 ...

  8. 获取win10壁纸

    执行命令会将所有壁纸拷贝到桌面上的wallpaper文件夹内 bat xcopy %LOCALAPPDATA%\Packages\Microsoft.Windows.ContentDeliveryMa ...

  9. 操作系统 - Linux操作系统 - Centos - Centos7 - 安装|命令|使用汇总

    镜像: http://mirrors.aliyun.com/centos/7/isos/x86_64/http://archive.kernel.org 网络配置 - DHCP  # /etc/res ...

  10. 红帽学习笔记[RHCSA] 第五课[用户、权限相关]

    第五课 用户权限 查看文件的权限 [kane@localhost /]$ ll total 36 ----------. 1 root root 1751 Aug 22 20:58 ~ lrwxrwx ...