感觉还是蛮简单的
因为高斯消元中i、j下标敲反了,跪了几发。。。
我们可以建立形似a[i]^x1^x2^...xn = b[i]的方程组
再解方程就可以了
题中给出i,j表明第i个开关会影响第j个灯
也就意味着第j个灯受xi影响,不要弄反了
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 50
using namespace std;
int a[MAXN], b[MAXN];
int c[MAXN][MAXN];
void print(int n) {
for(int i=0; i<n; ++i) {
for(int j=0; j<=n; ++j) {
printf("%d ", c[i][j]);
}
puts("");
}
}
int gauss(int n) {
int i, j, k, r;
for(i=0; i<n; ++i) {
r = i;
for(j=i+1; j<n; ++j)
if(c[j][i] > c[r][i])
r = j;
if(r != i) {
for(k=0; k<=n; ++k)
swap(c[i][k], c[r][k]);
}
for(j=i+1; j<n; ++j) {
if(c[j][i]) {
for(k=0; k<=n; ++k)
c[j][k] ^= c[i][k];
}
}
}
//print(n);
int cnt = 0;
for(i=0; i<n; ++i) {
for(j=0; j<=n; ++j)
if(c[i][j] == 1) {
if(j == n)
return -1;
++cnt;
break;
}
}
return n-cnt;
}
int main(void) {
int T, n;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
for(int i=0; i<n; ++i) {
scanf("%d", &a[i]);
}
for(int i=0; i<n; ++i) {
scanf("%d", &b[i]);
b[i] ^= a[i];
c[i][n] = b[i];
c[i][i] = 1;
}
int x, y;
while(scanf("%d%d", &x, &y)) {
if(x==0 && y==0)
break;
--x; --y;
c[y][x] = 1;
}
//print(n);
//puts("");puts("");puts("");
int ans = gauss(n);
if(ans == -1) puts("Oh,it's impossible~!!");
else cout << (1ll<<ans) << endl;
}
return 0;
}