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 }

你可能感兴趣的:(poj)