这题答案就是2^自由元的数目,原因是自由元可以取1或者0,所以就是ans<<1
由于只要求自由元的数目,所以高斯消元可以直接消后面的,不做前面的了,对答案没有影响
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #define MAXN 35 6 using namespace std; 7 int a[MAXN][MAXN]; 8 int gauss(int m,int n){ 9 int ret=0,line=1; 10 for(int k=1;k<=m;k++){ 11 int i=line; 12 while(i<=m){if(a[i][k])break;i++;} 13 if(i>m){ret++;continue;}//自由元 14 if(i!=line){for(int j=k;j<=n;j++)swap(a[i][j],a[line][j]);} 15 for(i=line+1;i<=m;i++){ 16 if(a[i][k]){ 17 for(int j=k;j<=n;j++){ 18 a[i][j]^=a[line][j]; 19 } 20 } 21 } 22 line++; 23 } 24 for(int i=line;i<=m;i++)if(a[i][n])return -1; 25 //最后一定都消成0了,所以a[i][n]必须为0才符合题意 26 return ret; 27 } 28 int n; 29 void solve(){ 30 memset(a,0,sizeof(a)); 31 scanf("%d",&n); 32 for(int i=1;i<=n;i++)scanf("%d",&a[i][n+1]); 33 int x,y; 34 for(int i=1;i<=n;i++){scanf("%d",&x);a[i][n+1]^=x;} 35 for(int i=1;i<=n;i++){a[i][i]=1;} 36 while(1){ 37 scanf("%d%d",&x,&y); 38 if(!x&&!y)break; 39 a[y][x]=1; 40 } 41 int ans=gauss(n,n+1); 42 if(-1==ans)printf("Oh,it's impossible~!! "); 43 else printf("%d ",1<<ans); 44 } 45 int main() 46 { 47 // freopen("data.in","r",stdin); 48 int T; 49 scanf("%d",&T); 50 while(T--){ 51 solve(); 52 } 53 return 0; 54 }