題目
現有N個開關,它們有on和off兩種狀態,還有M個電燈泡。開關編號從1到N,電燈泡編號從1到M。電燈泡i和Ki個的開關鏈接在一塊兒。這些開關的編號從Si1,Si2,Si3,Si4,....Siki.電燈泡i的ki個開關中,狀態爲on的開關的個數若是和pi的值相等的時候,電燈泡ki將會亮起。python
可以讓全部的燈泡亮起的的開關組合有多少種?app
條件spa
輸入
要求如下面的方式輸入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和開關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
解釋
爲了保證電燈泡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
這裏簡單描述爲
代碼
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)