poj1830 高斯消元法

来源:互联网 发布:怎么用u盘安装mac系统 编辑:程序博客网 时间:2024/06/03 14:04
/** * poj1830 高斯消元法(线性代数,矩阵求秩)  * 就是一个解二进制的线性方程组,求解的个数,如果增广阵和系数阵的秩不等,那就无解,否则解的个数是2^(n-秩) * 求秩的过程就是逐行消去的过程,最左列为1的行下面,该列都消去为0,最后统计非全0的行就是秩了 * 这个题一上来先把xy搞混了,结果WA了好多次都没搞清楚错在哪儿 后来索性试了一下,才解决了问题 */#include <cstdio>#include <iostream>#include <cmath>using namespace std;const int MAX_NUM = 30;bool sw[MAX_NUM][MAX_NUM];bool start[MAX_NUM],end[MAX_NUM],target[MAX_NUM];void swap(bool& a,bool& b){    bool tmp = a;    a=b;    b=tmp;}int main(){    int k,n,tmp,x,y;    scanf("%d",&k);    while(k--){        scanf("%d",&n);        for(int i=0;i<n;++i){            for(int j=0;j<n;++j){                sw[i][j] = (i==j);            }        }        for(int i=0;i<n;++i){            scanf("%d",&tmp);            start[i] = (tmp == 1);        }        for(int i=0;i<n;++i){            scanf("%d",&tmp);            end[i] = (tmp == 1);            target[i] = start[i] ^ end[i];        }        //scanf("%d%d",&x,&y);        scanf("%d%d",&y,&x);        while(x!=0 && y!=0){            sw[x-1][y-1] = true;            //scanf("%d%d",&x,&y);            scanf("%d%d",&y,&x);        }        int op_row,op_col,rp,cp;        //逐行,找到最高位的true,与当前最上面的行互换,将下面该位为true的行与该行做异或        for(op_row=0,op_col=0;op_row<n,op_col<n;++op_row,++op_col){//op_col表示当前最高列            int maxRow = op_row;            //查找col列为true的行            for(rp = op_row; rp < n; rp++){                if(sw[rp][op_col]){                    maxRow = rp;                      break;                }             }            if(maxRow != op_row){                for(cp = op_col; cp < n; cp++){                    swap(sw[op_row][cp], sw[maxRow][cp]);                                    }                swap(target[op_row],target[maxRow]);            }                  if(rp >= n)               {                  op_row--;                  continue;              }              for(rp = op_row + 1; rp < n; rp++)              {                  if(!sw[rp][op_col]) continue;                  for(cp = op_col; cp < n; cp++){                    sw[rp][cp] ^= sw[op_row][cp];                }                target[rp] ^= target[op_row];               }          }        bool flag = true;        //检查是否有解        for(int i=n-1;i>=op_row;--i){            if(target[i]){                flag = false;                printf("Oh,it's impossible~!!\n");                break;            }        }        if(flag){            printf("%d\n", 1<<(n-op_row) );        }    }    return 0;}

0 0