链接: http://poj.org/problem?id=1830
构造线性方程组A*X=B;
高斯消元解线性方程组。系数矩阵为D[x][y]的含义为第y个开关能够影响第x盏灯。B[i]表示第i盏灯是否需要变化是则为1,否则为0.

1 #include <stdio.h> 2 #include <string.h> 3 int N, begin[50], end[50], d[50][50]; 4 void Gauss( ) 5 { 6 int i, j, k, p, t; 7 for( i=1, j=1; i<=N, j<=N; i++, j++ ){ 8 for( p=i; p<=N; p++ ){ 9 if(d[p][j])break; //找到最前面不是0的一行 10 } 11 if( p==N+1 ){ // 如果是0找下一列,还是从当前行 12 i--; 13 continue; 14 } 15 if( p!=i ){ 16 for( k=1; k<=N+1; k++ ){//交换行 17 t=d[p][k]; 18 d[p][k]=d[i][k]; 19 d[i][k]=t; 20 } 21 } 22 for( k=i+1; k<=N; k++ ){//消元 23 if(!d[k][j])continue; 24 for( t=j; t<=N+1; t++ ){ 25 d[k][t]^=d[i][t]; 26 } 27 } 28 29 } 30 for( k=i; k<=N; k++ ){//判断系数矩阵的秩和增广矩阵的秩是否相等 31 if( d[k][N+1] ){ 32 puts( "Oh,it's impossible~!!" ); 33 return; 34 } 35 } 36 printf("%d\n", (1<<(N+1-i)) );// 自由解个数 37 } 38 int main( ) 39 { 40 int T, a, b; 41 scanf( "%d", &T ); 42 while( T -- ){ 43 scanf( "%d", &N ); 44 for(int i=1; i<=N; ++ i){ 45 scanf( "%d", &begin[i] ); 46 } 47 memset( d, 0, sizeof d ); 48 for(int i=1; i<=N; ++ i){ 49 scanf( "%d", &end[i] ); 50 d[i][N+1]=begin[i]^end[i]; 51 d[i][i]=1; 52 } 53 54 while( scanf("%d%d", &a, &b), a+b ){ 55 d[b][a]=1; 56 } 57 Gauss( ); 58 } 59 return 0; 60 }