POJ - 1222 高斯消元基础题,解异或方程组

POJ 1222

题意:给出5行6列的矩阵,每个位置有一个数,0或1。在(i,j)的位置按一下,则它自身和它上下左右的位置都要反转,要通过这样的操作把所有位置都变为0。输出一个5行6列的矩阵,1表示这个位置按了,0表示没按。

总结:高斯消元,还没有完全弄明白,参考大神博客强行码了一发。。。

// POJ - 1222 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<bitset>
#include<vector>
#include<set>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define F(i,a,b)  for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 40;

int a[N][N], ans[N];    //ans[]为解集
int gauss(int equ, int var) //有equ个方程,var个变元,增广矩阵行数[0, equ - 1],列数[0, var]
{
    FF(i,0,var) ans[i]=0;   //初始化
    int col=0, row=0, maxRow;   //下面转换为阶梯矩阵,col表示当前正在处理的这一列,maxR表示当前这个列中元素绝对值最大的行
    for( ; row<equ && col<var; row++, col++) {  //枚举当前正在处理的行,找到该col列元素绝对值最大的那行与第k行交换
        maxRow=row;
        F(i,row+1,equ) {
            if(abs(a[maxRow][col]< abs(a[i][col])))
                maxRow=i;
        }
        if(maxRow!=row) {   //与第row行交换
            F(j,row,var+1) {
                swap(a[row][j], a[maxRow][j]);
            }
        }
        if(a[row][col]==0) {    //说明该col列第row行以下全是0,处理当前行的下一列
            row--;
            continue;
        }
        F(i,row+1,equ) {    //枚举要删的行
            if(a[i][col]!=0) {
                F(j,col,var+1) {
                    a[i][j]^= a[row][j];
                }
            }
        }
    }
    for(int i=var-1; i>=0; i--) {
        ans[i]= a[i][var];
        F(j,i+1,var) {
            ans[i]^= (a[i][j]&&ans[j]);
        }
    }
    return 0;
}
int main()
{
    int n;  cin>>n;
    FF(cas,1,n) {
        mes(a,0);
        F(i,0,30) cin>>a[i][30];
        F(i,0,5) F(j,0,6) { //构建系数矩阵
            int t=i*6+j;
            a[t][t]=1;
            if(i>0) a[(i-1)*6+j][t]=1;  //这里不太懂为什么
            if(i<4) a[(i+1)*6+j][t]=1;
            if(j>0) a[i*6+j-1][t]=1;
            if(j<5) a[i*6+j+1][t]=1;
        }
        gauss(30,30);
        printf("PUZZLE #%d\n", cas);
        F(i,0,30) {
            cout<<ans[i];
            if((i+1)%6==0 ) cout<<endl;
            else cout<<" ";
        }
    }

    return 0;
}
View Code
posted @ 2017-01-17 20:03  v9fly  阅读(291)  评论(0编辑  收藏  举报