题意:有n个开关和m个灯泡,每个灯泡关联k个开关,当灯泡关联的开关开着的数量取余2等于p时,灯泡亮起,现在问你有多少种方式让灯泡全亮。
思路:利用二进制,直接模拟所有状态即可。
代码:
#include<bits/stdc++.h> #define ULL unsigned long long #define LL long long #define Max 15 #define mem(a,b) memset(a,(int)b,sizeof(a)); #define pb push_back #define mp make_pair const LL mod=1e9+7; const ULL base=131; const LL LL_MAX=9223372036854775807; using namespace std; int n,m; int p[Max],c[Max],on[Max]; map<pair<int,int>,int>mm; bool check(){ mem(on,0); for(int i=n;i>=1;i--){ if(c[i]){ for(int j=1;j<=m;j++) if(mm[mp(j,i)]==1) on[j]++; } } for(int i=1;i<=m;i++){ if((on[i]%2)!=p[i]) return 0; } return 1; } int fun(){ int len=pow(2,n)-1,now,op,ans=0; for(int i=0;i<=len;i++){ now=i; for(int j=n;j>=1;j--){ op=now%2; now/=2; c[j]=op; } if(check()) ans++; } return ans; } int main() { scanf("%d%d",&n,&m); int t,sw; for(int i=1;i<=m;i++){ scanf("%d",&t); for(int j=0;j<t;j++){ scanf("%d",&sw); mm[mp(i,sw)]=1; } } for(int i=1;i<=m;i++) scanf("%d",&p[i]); printf("%d\n",fun()); return 0; }