AtCoder Context 128 C Swtich(控制開關)

題目
現有N個開關,它們有on和off兩種狀態,還有M個電燈泡。開關編號從1到N,電燈泡編號從1到M。電燈泡i和Ki個的開關鏈接在一塊兒。這些開關的編號從Si1,Si2,Si3,Si4,....Siki.電燈泡i的ki個開關中,狀態爲on的開關的個數若是和pi的值相等的時候,電燈泡ki將會亮起。python

可以讓全部的燈泡亮起的的開關組合有多少種?app

條件spa

  • 1<=N,M<=10
  • 1<=Ki<=N
  • 1<=Sij<=N
  • Sia != Sib (a != b)
  • Pi爲0或者1
  • 全部的輸入都爲整數

輸入
要求如下面的方式輸入code

N M
k1 s11 s12 ...... s1k1
.
.
km sm1 sm2 ...... smkm
p1 p2 ...... pm

輸出
可以讓全部燈泡都亮的開關的組合數blog

例1
輸入input

2 2
2 1 2
1 2
0 1

輸出it

1

解釋for循環

  1. 對於電燈泡1,這些開關中,狀態是on的開關的個數爲偶數的時候會亮:開關1,開關2
  2. 對於電燈泡2,這些開關中,狀態時on的開關的個數爲奇數的時候會亮:開關2

對於開關1和開關2來講,全部的狀況是如下
(on,on),(on,off),(off,on),(off,off)
可以知足以上條件的只有(on,on),暨開關1開,開關2開。
最後輸出1class

例2
輸入循環

2 3
2 1 2
1 1
1 2
0 0 1

輸出

0

解釋

  1. 對於電燈泡1,這些開關中,狀態是on的開關的個數爲偶數的時候會亮:開關1,開關2
  2. 對於電燈泡2,這些開關中,狀態是on的開關的個數爲偶數的時候會亮:開關1
  3. 對於電燈泡3,這些開關中,狀態是on的開關的個數爲奇數的時候會亮:開關2

爲了保證電燈泡2開,開關1要off
爲了保證電燈泡3開,開關2要on
這種狀況下,電燈泡1,不可能亮起
因此,讓全部的電燈泡都能亮的狀況是不存在的,輸出爲0

例3
輸入

5 2
3 1 2 5
2 2 3
1 0

輸出

8

解題思路

讀懂題目

遍歷全部的開關關閉狀況,看看是否是知足全部的電燈泡亮起的條件

N表明開關的數量,N的最大值是10,開關有on,off兩種狀況,因此一共有2的10次方,1024種狀況。一個for循環,時間上老說是足夠的

那麼問題來了,如何用代碼實現這1024種狀況呢
答案就在比特運算

打個比方,有3個開關,一共2的3次方種狀況,一共8種狀況

for i in range(2**3):
  print(i)

這樣能輸出

0
1
2
3
4
5
6
7

可是實際上能夠當作

000
001
010
011
100
101
110
111

其中011能夠當作
開關3(OFF)
開關2(ON)
開關1(ON)

這裏咱們固然可以從肉眼中簡單判斷出以上的狀況,那麼如何從代碼中判斷,011的狀況中第三個開關是OFF呢

有一個技巧
判斷開關3是否爲ON

3 >> 2 & 1

這裏簡單描述爲

比特運算.png

代碼

def calculate(n,m,arr,p):
    total = 0
    for i in range(2**n):
        #某一種狀況

        check = [False for i in range(m)]
        for indexOfBlub in range(len(arr)):
            # 第幾個燈泡
            onNumOfTheBlub = 0
            for indexOfSwitch in range(len(arr[indexOfBlub])):
                if i >> (arr[indexOfBlub][indexOfSwitch] - 1) & 1:
                    onNumOfTheBlub += 1

            # 該燈泡全部的switch都循環結束之後,統計on的數量是否和給定的同樣

            if onNumOfTheBlub % 2 == p[indexOfBlub]:
                check[indexOfBlub] = True

        if all(check):
            total += 1

    return total

S = input()
S = S.split(" ")
n = int(S[0])
m = int(S[1])
inputArr = []
for i in range(m):
    S = input()
    inputArr.append([int(s) for s in S.split(" ")][1:])

S = input()
inputP = [int(s) for s in S.split(" ")]

res = calculate(n,m,inputArr,inputP)
print(res)
相關文章
相關標籤/搜索