P2622 关灯问题II(关灯问题)

https://www.luogu.org/problem/P2622

题目描述

现有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

扫描二维码关注公众号,回复: 7545211 查看本文章
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 struct node
 6 {
 7     int data, step;
 8 } str[100000], q, now;
 9 
10 
11 map <long long, bool> book;
12 
13 void opera(int x, int k)
14 {
15     if(x==0) return;
16     else
17     {
18         opera(x/k, k);
19         printf("%d", x%k);
20     }
21 }
22 
23 int main()
24 {
25     int n, m, a[105][105];
26     int i, j, top, tail, cur, re;
27     scanf("%d %d", &n, &m);
28     for(i=1; i<=m; i++)
29     {
30         for(j=1; j<=n; j++)
31         {
32             scanf("%d", &a[i][j]);
33         }
34     }
35 
36     top = 0;
37     tail = 0;
38     q.data = (1<<n)-1;
39     q.step = 0;
40 
41     str[top++] = q;
42     book[q.data] = 1;
43 
44     re = -1;
45     while(top>tail)
46     {
47         now = str[tail++];
48         for(i=1; i<=m; i++) //开关
49         {
50             cur = now.data;
51             for(j=1; j<=n; j++) //
52             {
53                 if(a[i][j]==1&&(cur&1<<(j-1))) cur = cur ^ (1<<(j-1));
54                 else if(a[i][j]==-1) cur = cur | (1<<(j-1));
55             }
56 
57             if(cur==0)
58             {
59                 re = now.step + 1;
60                 break;
61             }
62 
63             if(book[cur]==0)
64             {
65 //                opera(cur, 2);
66 //                printf(" %d\n", now.step+1);
67                 book[cur] = 1;
68                 q.data = cur;
69                 q.step = now.step + 1;
70                 str[top++] = q;
71             }
72         }
73         if(i<=m) break;
74     }
75 
76     printf("%d\n", re);
77     return 0;
78 }

猜你喜欢

转载自www.cnblogs.com/0xiaoyu/p/11722588.html