典型的開燈關燈問題
行列關係找準就好
數組忘了初始化跪了幾發。。。
代碼如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 100
using namespace std;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
void print(int n) {
for(int i=1; i<=n; ++i) {
for(int j=1; j<=n+1; ++j)
printf("%d ", a[i][j]);
puts("");
}
}
int gauss(int m, int n) {
int i, j, k, col, max_r;
col = 1;
for(k=1; k<=n&&col<=m; ++k, ++col) {
max_r = k;
for(i=k+1; i<=n; ++i) {
if(a[i][col] > a[max_r][col])
max_r = i;
}
if(max_r != k)
for(j=1; j<=m+1; ++j)
swap(a[k][j], a[max_r][j]);
if(a[k][col] == 0) {
--k;
continue;
}
for(i=k+1; i<=n; ++i) {
if(a[i][col]) {
for(j=col; j<=m+1; ++j)
a[i][j] ^= a[k][j];
}
}
}
//print(n);
for(int i=k; i<=n; ++i)
if(a[i][m+1])
return -1;
return m+1-k;
}
int main(void) {
int m, n, T, q, k, x;
scanf("%d", &T);
for(int _=1; _<=T; ++_) {
printf("Case %d:\n", _);
memset(b, 0, sizeof(b));
scanf("%d%d", &n, &m);
for(int i=1; i<=m; ++i) {
scanf("%d", &k);
while(k--) {
scanf("%d", &x);
b[x][i] = 1;
}
}
scanf("%d", &q);
while(q--) {
memcpy(a, b, sizeof(b));
for(int i=1; i<=n; ++i) {
scanf("%d", &a[i][m+1]);
}
//print(n);
int ans = gauss(m, n);
if(ans == -1) puts("0");
else cout << (1ll<<ans) << endl;
}
}
return 0;
}