题目描述

现有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. 我写过的bug...

    添加对,更新和查询出错 因为只写了bean里只写了se't方法,没有写get 多条件联合查询,后一个条件没用 写xml里面复制上一行,忘记把变量名改了(propertyValue没改成register ...

  2. 目标双站定位仿真C++代码

    point-position2 初步完善版. 不再使用eigen库,行列式直接计算得出结果.判断共面异面分别处理. 先提取双站获得图像的匹配特征点,由双站位置信息解析目标位置. // point-po ...

  3. 2018 icpc 青岛

    https://zoj.pintia.cn/contests/91827364639/problems C 要把这两个二进制串变为相同,需要先看哪些位置不同,设为数组c,某位为1则两位不同. 分1形成 ...

  4. ffmpeg mp4 to wmv and wmv to mp4

    //大小=>变小ffmpeg -i 1.mp4 -b:v 2M -vcodec msmpeg4 -acodec wmav2 1_mp4.wmv//大小=>变大ffmpeg -i 1.mp4 ...

  5. Excel导入导出工具——POI XSSF的使用

    工具简介 POI是Apache提供的一款用于处理Microsoft Office的插件,它可以读写Excel.Word.PowerPoint.Visio等格式的文件. 其中XSSF是poi对Excel ...

  6. QT Desinger设计窗体应用程序框架

    目录 目录 前言 系统软件 QT Designer Using QT Designer Open QTDesigner Tool Widget Box QT Designer的布局 属性栏 示例 i ...

  7. 使用Postman对HTTP接口进行功能测试

    一.工具说明 Postman是一种网页调试与发送网页http请求的工具.我们可以用来很方便的模拟get或者post或者其他方式的请求来调试接口. 二.应用场景 1.Get请求 get请求通过接口参数拼 ...

  8. 算法之美&数据结构与算法复习

    1.归并两个有序链表(归并排序) 2.最小路径和--BP解法 3.计算int sqrt(x)--二分解法 4.趣味面试题 5.跳步游戏(Jump_Game)--后向回溯算法 6.Excel列号转十进制 ...

  9. rename批量修改文件名

    批量改名: 如文件,批量修改,把hello去掉[root@localhost wang]# ll-rw-r--r-- 1 root root 0 5月 14 02:36 a.hello.txt-rw- ...

  10. 比较css中单位px,em和rem的区别

    国内的设计师大都喜欢用px,而国外网站大都喜欢用em和rem,那么三者有什么区别,又各自有什么优劣呢? px特点 1. IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的原 ...