poj1830 开关问题解题报 <高斯消元>

链接: http://poj.org/problem?id=1830

构造线性方程组A*X=B;

高斯消元解线性方程组。系数矩阵为D[x][y]的含义为第y个开关能够影响第x盏灯。B[i]表示第i盏灯是否需要变化是则为1,否则为0.

View Code
 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 }
原文地址:https://www.cnblogs.com/jian1573/p/2612836.html